【发布时间】:2015-02-08 09:38:37
【问题描述】:
我正在将 handmadehero.org 项目中的 C 代码转换为 Delphi 代码。我在特定作品上遇到了性能问题:
原文:
inline real32
Win32GetSecondsElapsed(LARGE_INTEGER Start, LARGE_INTEGER End)
{
real32 Result = ((real32)(End.QuadPart - Start.QuadPart) /
(real32)GlobalPerfCountFrequency);
return(Result);
}
我的版本:
function Win32GetSecondsElapsed(Start, &End : LARGE_INTEGER): real32; inline;
begin
Result := (&End.QuadPart - Start.QuadPart) / GlobalPerfCountFrequency;
end;
调用 sleep 函数后,有这段代码来确保我们达到目标帧率:
SleepMilliSeconds = <some code that calcs how long to wait to hit target frame rate>
Sleep(SleepMilliSeconds);
real32 TestSecondsElapsedForFrame = Win32GetSecondsElapsed(LastCounter, Win32GetWallClock());
Assert(TestSecondsElapsedForFrame < TargetSecondsPerFrame);
如果我使用相同的代码(只是它是 Delphi 版本),我会收到断言错误。
如果我把代码改成这样:
TestSecondsElapsedForFrame := ((LastCounter.QuadPart - Win32GetWallClock().QuadPart) / GlobalPerfCountFrequency);
Assert(TestSecondsElapsedForFrame < TargetSecondsPerFrame);
错误消失了,所以在 Delphi 中调用该函数需要足够长的时间来推动我完成睡眠所允许的时间。 有谁知道我该如何解决这个问题? 我尝试将 Win32GetSecondsElapsed 中的参数更改为作为指针传递,但它没有帮助。 我认为这可能是因为它是按值传递的并且需要制作副本,但事实并非如此。 我认为'inline'指令没有生效。
我相信 Delphi 应用程序应该有可能与 C 应用程序一样快。
【问题讨论】:
-
调用一个函数应该不会花费太多时间,但在这种特殊情况下可能会出现问题。您必须检查生成的代码以确定是什么/为什么。
-
请注意,在这种情况下“调用函数”甚至无关紧要。由于在这两种情况下都将“结束时间”作为参数!
-
我认为在游戏应用程序中睡觉并不明智。每次应用程序计算/绘制下一帧时,它应该计算自上次调用以来应该计算多少帧。然后计算所有这些,只画最后一个。有时它只是一个 NOP 调用,有时你必须根据当前系统状态计算一些帧。
-
即使在 GPU 速度较慢的系统上,您也不会真正失去时间同步,而且眼睛/大脑感觉更自然。
-
我不是在设计代码的工作方式,我只是在翻译它。如果您想讨论代码如何工作的原因,请随时访问 handmadehero.org。 Casey Muratori 很乐意解决您的疑虑,因为此代码仅用于教育目的。
标签: c++ performance delphi function-call