MulDiv 的效率是否会低于存储已知值并在其他代码中进行数学运算
我正在使用 Delphi 2007 并开发一些演示软件。我当前正在开发的模块是视频的转换过滤器。我使用的转换代码(TPicShow 的 PSEffects 单元)需要基于帧尺寸和转换进度的 X 和 Y 值。 代码
Type
TPercent = 0..100;
var
ATo : TBitmap; //
Prog : Integer; //Progress of the transition
if ATo.Width >= ATo.Height then
begin
X := MulDiv(ATo.Width, Prog, High(TPercent));
Y := MulDiv(X, ATo.Height, ATo.Width);
end
else
begin
Y := MulDiv(ATo.Height, Prog, High(TPercent));
X := MulDiv(Y, ATo.Width, ATo.Height);
end;
这是我尝试优化的
,发现我可以保存恒定的计算(直到 ATo 的尺寸发生变化)并删除每帧 2 个除法计算。所以这会是这样的,
{All of these are calculated when the dimensions of ATo Change}
WDP : real; // width divided by High(TPercent)
HDW : real; // Height divided by width
HDP : real; // Height divided by High(TPercent)
WDH : real; // Width divided by Height
if ATo.Width >= ATo.Height then
begin
X := Trunc(WDP * Prog);
Y := Trunc(HDW * X);
end
else
begin
Y := Trunc(HDP * Prog);
X := Trunc(WDH * Y);
end;
听起来不错,但没有 MulDiv 的实际代码,我无法确定。如果它只是这样做(非常简化)
MulDiv(a,b,c : Integer)
begin
Round((A*B)/C);
end
那么我知道我的更改会更有效,但是如果 MulDiv 在优化函数方面做了任何非常酷的事情(我认为它可能)那么我不确定我的更改是否会给我带来好处任何事物。
我的改变会更有效率吗?
编辑:我还没有实现这个,我只是在考虑这个想法。
I am using Delphi 2007 and working on some presentation software. The current module I am working on is the transition filter for video. The transition code I am using (TPicShow's PSEffects unit) requires and X and a Y value based on the dimensions of the frame and the progress of the transition. Here is the code
Type
TPercent = 0..100;
var
ATo : TBitmap; //
Prog : Integer; //Progress of the transition
if ATo.Width >= ATo.Height then
begin
X := MulDiv(ATo.Width, Prog, High(TPercent));
Y := MulDiv(X, ATo.Height, ATo.Width);
end
else
begin
Y := MulDiv(ATo.Height, Prog, High(TPercent));
X := MulDiv(Y, ATo.Width, ATo.Height);
end;
I am trying to optimize this and saw that I could save the calculations that would be constant (until the dimensions of ATo change) and remove 2 division calculations each frame.
So it would be something like
{All of these are calculated when the dimensions of ATo Change}
WDP : real; // width divided by High(TPercent)
HDW : real; // Height divided by width
HDP : real; // Height divided by High(TPercent)
WDH : real; // Width divided by Height
if ATo.Width >= ATo.Height then
begin
X := Trunc(WDP * Prog);
Y := Trunc(HDW * X);
end
else
begin
Y := Trunc(HDP * Prog);
X := Trunc(WDH * Y);
end;
It sounds good but not having the actual code of MulDiv I cant be sure. If it simply does (very simplified)
MulDiv(a,b,c : Integer)
begin
Round((A*B)/C);
end
Then I know my change will be more efficient, however if MulDiv does anything very cool with optimizing the function (Which I'd thing it might) then I'm not sure if my change would net me anything.
Would my change be more efficient?
EDIT: I have not yet implemented this, I'm just entertaining the notion.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
正如其他人所说,您应该使用分析器来识别热点。
一旦您确定了它们,在您的情况下,在多媒体应用程序中找到比当前代码更快的东西可能需要您了解 SIMD 机器语言指令,并且可能需要您编写替换的手动优化的汇编代码,以获得任何更快的结果。
使用浮点类型在 Pascal 中自己编写一些东西,不太可能带来任何性能改进。缓存中间结果可能会导致内存使用量呈指数级增长,而速度只会有适度的提高,这实际上可能会减慢可能发生虚拟机分页(颠簸)的系统的速度。
As other people have stated, you should be looking to a profiler to identify hotspots.
Once you have identified them, finding something faster than your current code, in your case, in a multimedia application, might require that you learn about SIMD machine language instructions, and might require that you write replacement hand-optimized assember code, to obtain any faster results.
Writing something yourself in Pascal, using floating point types, is VERY unlikely to result in any performance improvements. Caching intermediate results will probably result in exponential increases in memory usage, with only a moderate improvement in speed, that might actually slow you down on systems where vm paging (thrashing) is likely to occur.
您找不到 MulDiv 因为它是一个 WinAPI 函数。不过,我怀疑,因为它在 WinAPI 本身中大量使用,所以它可能是一些经过良好优化的汇编代码,而不仅仅是几个函数调用。
至于您的更改是否会更有效,确定这一点的唯一方法是对两种方式的代码进行分析,看看哪种更快。在此处搜索“Delphi profiler”以获取一些建议(如果您使用的是 Delphi XE,则可以使用附带的 AQTime)。
顺便说一句,当您谈论优化等问题时,指示您实际使用的 Delphi 版本通常非常有用,因为编译器的更改可能会导致答案发生变化。
You can't find the actual code of MulDiv because it's a WinAPI function. I'd suspect, though, that because it's used heavily in the WinAPI itself, it's probably some pretty well optimized assembler code, rather than just a couple of function calls.
As far as whether your change would be more efficient, the only way to determine that is to profile the code both ways and see which is faster. Search here for "Delphi profiler" for some suggestions (if you're using Delphi XE, you can use the included AQTime).
BTW, when you're talking about things like optimization and so forth, it's frequently very useful to indicate which Delphi version you're actually using, as changes in the compiler can make a difference in the answers.
如果对使用整数运算实现的 MulDiv 的调用效率低下并且是性能问题的根源,我会感到非常惊讶。你给你的节目安排好时间了吗?您是否使用分析器来识别应用程序中的热点?
我个人认为从整数转换到双精度浮点运算不太可能带来性能改进。
无论如何,我的猜测是您在显示的代码之后调用了其他代码,这些代码使用
X
和Y
并且消耗了更多数量级的 CPU比这个小片段。您可能不会计算X
和Y
然后丢弃它们:您如何处理它们?编辑:MulDiv 的 Wine 实现大概非常接近 Windows 的实现,其本质是这样的:
I'd be very surprised if calls to MulDiv, which is implemented using integer operations, were inefficient and the source of your performance problems. Have you timed your program? Have you used a profiler to identify the hot spots in your app?
Personally I think it is unlikely that a switch from integer to double precision floating point operations is likely to yield performance improvements.
In any case, my guess would be that you have other code which you call after the code you have shown, which uses
X
andY
and which consumes orders of magnitude more CPU than this little snippet. You presumably don't calculateX
andY
and then discard them: what do you do with them?EDIT: The Wine implementation of MulDiv is presumably very close to the Windows one, and the guts of that is so: