gpt4 book ai didi

c# - 使用 QueryPerformanceFrequency() 和 QueryPerformanceCounter() 将我的 C++ 代码转换为 C#?

转载 作者:行者123 更新时间:2023-11-30 21:38:53 26 4
gpt4 key购买 nike

我一直在将我的游戏从 C++ 转换为 C#。我很好奇计时器将如何在 C# 缺少 QueryPerformanceFrequency() 和 QueryPerformanceCounter() 的情况下工作,因为我需要总时间和增量。如何使用我以前拥有的函数将我的代码转换为 C#?

我将逐节介绍:

我正在为 C++ 使用此计时器代码:

#include "HPTimer.h"

/// <summary>
/// HP Timer constructor
/// </summary>
HPTimer::HPTimer()
{
init();
}

/// <summary>
/// Initializes the timer
/// </summary>
void HPTimer::init()
{
LARGE_INTEGER t;

QueryPerformanceFrequency(&t);
m_frequency = t.QuadPart;

reset();
}

/// <summary>
/// Sets the current time.
/// </summary>
void HPTimer::reset()
{
LARGE_INTEGER t;

QueryPerformanceCounter(&t);

m_startTime = t.QuadPart;
m_currentCallToUpdate = t.QuadPart;
m_lastCallToUpdate = t.QuadPart;
}

/// <summary>
/// Updates the timer so it's current.
/// </summary>
void HPTimer::update()
{
LARGE_INTEGER t;

m_lastCallToUpdate = m_currentCallToUpdate;
QueryPerformanceCounter(&t);
m_currentCallToUpdate = t.QuadPart;
}

/// <summary>
/// Gets the total time since reset was called.
/// </summary>
/// <returns>Returns the total time.</returns>
double HPTimer::getTimeTotal()
{
double d;

d = m_currentCallToUpdate - m_startTime;
return d / m_frequency;
}

/// <summary>
/// Gets the difference between two calls of update.
/// </summary>
/// <returns>Returns the delta time.</returns>
double HPTimer::getTimeDelta()
{
double d;

d = m_currentCallToUpdate - m_lastCallToUpdate;
return d / m_frequency;
}

Microsoft 的解决方案如下: https://msdn.microsoft.com/en-us/library/ff650674.aspx

// QueryPerfCounter.cs
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
public class QueryPerfCounter
{
[DllImport("KERNEL32")]
private static extern bool QueryPerformanceCounter(
out long lpPerformanceCount);

[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(out long lpFrequency);

private long start;
private long stop;
private long frequency;
Decimal multiplier = new Decimal(1.0e9);

public QueryPerfCounter()
{
if (QueryPerformanceFrequency(out frequency) == false)
{
// Frequency not supported
throw new Win32Exception();
}
}

public void Start()
{
QueryPerformanceCounter(out start);
}

public void Stop()
{
QueryPerformanceCounter(out stop);
}

public double Duration(int iterations)
{
return ((((double)(stop - start)* (double) multiplier) / (double) frequency)/iterations);
}
}

虽然这看起来很有效,但它缺少我之前使用的几个部分:LARGE_INTEGER、QuadPart、获取总时间和获取时间增量。在 Microsoft 的代码中,他们有这个让我感到困惑的“迭代”论点。有没有一种方法可以转换我的代码,同时仍然使用我以前的函数?

编辑:我很好奇 LARGE_INTEGER/QuadPart。我去了这里: https://msdn.microsoft.com/en-us/library/windows/desktop/aa383713(v=vs.85).aspx我想 LARGE_INTEGER 在 C# 的世界(64 位)中真的很长。所以 t.QuadPart 被视为输出 long 值,对吧?

更新:查看答案后,我有以下转换(但仍需要确认)

public class HPTimer
{
private long m_startTime;
private long m_lastCallUpdate;
private long m_currentCallToUpdate;
private long m_frequency;
private Stopwatch m_stopWatch;

/// <summary>
/// HP Timer constructor
/// </summary>
public HPTimer()
{
Init();
}

/// <summary>
/// Initializes the timer
/// </summary>
public void Init()
{
m_stopWatch = Stopwatch.StartNew();
m_frequency = Stopwatch.Frequency;

Reset();
}

/// <summary>
/// Resets the current time.
/// </summary>
public void Reset()
{
m_startTime = Stopwatch.GetTimestamp();
m_currentCallToUpdate = Stopwatch.GetTimestamp();
m_lastCallUpdate = Stopwatch.GetTimestamp();
}

/// <summary>
/// Updates the timer so it's current.
/// </summary>
public void Update()
{
m_lastCallUpdate = m_currentCallToUpdate;
m_currentCallToUpdate = Stopwatch.GetTimestamp();
}

/// <summary>
/// Gets the total time since reset was called.
/// </summary>
/// <returns>Returns the total time.</returns>
public double GetTotalTime()
{
double d;

d = m_currentCallToUpdate - m_startTime;
return d / m_frequency;
}

/// <summary>
/// Gets the difference between two calls of update.
/// </summary>
/// <returns>Returns the delta time.</returns>
public double GetTimeDelta()
{
double d;

d = m_currentCallToUpdate - m_lastCallUpdate;

return d / m_frequency;
}
}

最佳答案

您可以使用 Stopwatch而不是非托管 Win32 API 来记录时间。示例:

//Equivalent to:
//Stopwatch stopWatch = new Stopwatch();
//stopWatch.Start();
Stopwatch stopWatch = Stopwatch.StartNew();

//Operation you want to measure

stopWatch.Stop();

//Timespan is a struct to hold time related info..
//e.g: Days, Hours, Seconds, Milliseconds, Ticks and TotalDays... etc
Timespan ts = stopWatch.Elapsed;

//Or you can simply get the time elapsed in milliseconds like this
long elapsed = stopWatch.ElapsedMilliseconds;


//QueryPerformanceFrequency
long frequency = Stopwatch.Frequency;

//QueryPerformanceCounter
long ticks = Stopwatch.GetTimestamp();

至于您关于 LARGE_INTEGER 的其他问题。根据 this page,它的 C# 等效项应该是:

//Specify struct size and field offsets by ourselves
[StructLayout(LayoutKind.Explicit, Size = 8)]
struct LARGE_INTEGER
{
[FieldOffset(0)]
public uint LowPart;
[FieldOffset(4)]
public int HighPart;

[FieldOffset(0)]
public long QuadPart;
}

关于c# - 使用 QueryPerformanceFrequency() 和 QueryPerformanceCounter() 将我的 C++ 代码转换为 C#?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45552470/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com