- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在将我的游戏从 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/
在循环遍历每种数据类型(整数、 double 、十进制和变量)的 100 万个随机数后,我试图测试数据类型之间的执行时间差异。我从 Microsoft Developer 网站获取了这段代码。我正在使
嘿,我正在使用 QueryPerformanceCounter 来计算该函数花费的时间(以毫秒为单位),但我收到了这个运行时错误: Run-Time Check Failure #2 - Stack
我正在使用 QueryPerformanceCounter 来测量某些函数/操作的时间。它曾经给我正确的数字,例如,我可以测试 Sleep(1000),它会返回非常接近 1 秒的时间。现在,它返回一个
我想使用 PerformanceCounter 来衡量执行某些操作需要多少时间。 我对 PerformanceCounter 和 C++ 了解不多。我在这里找到了一些代码: How to use Qu
我需要衡量我编写的函数的性能。由于我不能使用 C++11 并且我需要微秒,所以我使用了 windows.h 中的 QueryPerformanceCounter。 #include LARGE_IN
假设从 QueryPerformanceCounter 返回的计数是否安全?与上次系统启动后的时间有关?还是可以在系统运行时重置? MSDN 文章本身并不能保证这一点,但是我看到一些第 3 方信息(例
我正在使用 QueryPerformanceCounter 在我的应用程序中做一些计时。但是,在运行几天后,该应用程序似乎停止正常运行。如果我只是重新启动应用程序,它就会再次开始工作。这让我相信我的计
在 Windows 中通过分辨率较低的计时方法调用 QueryPerformanceCounter 是否会对性能产生影响? 最佳答案 虽然老了,this Dr Dobb's article很好地总结了
我正在考虑在两个同时处于事件状态的线程中重复调用(旋转)QueryPerformanceCounter。我不确定这是否真的是一个问题,因为我没有看到任何关于它的文章,但是 QueryPerforman
我创建了一个简单的程序来确定 QueryPerformanceCounter 调用需要多长时间。在我的计算机上大约需要 8 纳秒,但有时我会看到每次调用出现高达 500 微秒的峰值。 一些细节: Vi
在 linux 中是否有一个等效的 C 函数来读取 CPU 计数器及其频率? 我正在寻找类似于 QueryPerformanceCounter 函数的东西,它可以读取现代 CPU 中的 64 位计数器
嗨,我正在使用 QueryperformanceCounter 对 Delphi 中的一段代码进行计时。由于某种原因,我使用 QueryPerformanceCounter 得到的毫秒数与使用秒表得到
我需要使用 QueryPerformanceCounter Win32 API 格式化日期时间。格式为: HH:mm:ss.ffffff ,包含时分秒和微秒。我需要使用这个函数,因为另一个进程(用 C
#include "TIMER1.h" #include "MAIN.h" typedef unsigned _int64 uint64; void TASK1() { uint64 freq, s
我有一个等待 std::condition_variable 然后循环直到它完成的线程。 我试图滑动我在 opengl 中绘制的矩形。 在不使用 delta 的情况下一切正常,但我希望无论在哪台计算机
我想知道 Windows 函数 GetSystemTimePreciseAsFileTime 是否使用 QueryPerformanceCounter/RDTSC 计数器以亚微秒分辨率检索 UTC 时
我已经对这里找到的 PRIMATEs 密码做了一些切片实现:http://primates.ae/ (我用的是 120 位版本)。 我只用 C 语言制作并使用了 Intel Intrinsics,这样
我在 this post 中找到了有关使用 QueryPerformanceCounter 的有用信息但我面临一个我还没有找到答案的问题。 我正在为 Windows CE 6.0 开发一个应用程序,需
我正在研究在我们的系统中使用 QueryPerformanceCounter 的确切含义,并试图了解它对应用程序的影响。从我的 4 核单 CPU 机器上运行它可以看出,它需要大约 230ns 才能运行
鉴于 C# 中的 Stopwatch 类可以在下面使用类似三个不同计时器的东西,例如 系统定时器精度约为 +-10 ms,具体取决于可以使用 timeBeginPeriod 设置的计时器分辨率它可能约
我是一名优秀的程序员,十分优秀!