这个 Delphi 6 位图修改代码可以用 SIMD 或其他方法加速吗?
Posted
技术标签:
【中文标题】这个 Delphi 6 位图修改代码可以用 SIMD 或其他方法加速吗?【英文标题】:Can this Delphi 6 bitmap modification code be sped up with SIMD or another approach? 【发布时间】:2011-12-26 14:52:44 【问题描述】:我有一个可以实时修改位图的 Delphi 6 应用程序。目前我正在使用下面显示的代码来快速提高亮度和更改对比度。如果运算只是加法或乘法,我可以看到如何使用 SIMD,但由于涉及到加法和乘法,而且还有 Trunc() 操作将其限制在 a 的范围内字节,我不确定这里是否可以使用 SIMD。以下是我的问题:
-
SIMD 可以与此代码一起使用吗?您知道我可以使用的好的代码示例吗?我可以期待什么样的速度提升?
扫描线的(潜在)填充是否会成为问题?
关于加速代码的任何一般优化技巧?
;
// A fast version of this function would be to only allow range reductions
// as a power of 2 and then use shl operations instead of divisions.
procedure doBrightnessAndContrast(var clip: tbitmap; compressionRatio: double; shiftValue: Byte);
var
p0: PByte;
x,y: Integer;
begin
for y := 0 to clip.Height-1 do
begin
p0 := clip.scanline[y];
// Can't just do the whole buffer as a big block of bytes since the
// individual scan lines may be padded for CPU alignment.
for x := 0 to clip.Width - 1 do
begin
// Red
p0^ := IntToByte(Trunc(p0^ * compressionRatio) + shiftValue);
Inc(p0);
// Green
p0^ := IntToByte(Trunc(p0^ * compressionRatio) + shiftValue);
Inc(p0);
// Green
p0^ := IntToByte(Trunc(p0^ * compressionRatio) + shiftValue);
Inc(p0);
end;
end;
end;
【问题讨论】:
使用整数算术不是更好吗? @DavidHeffernan。好点子。我会将compressionRatio 和shiftValue 重铸为整数,看看我得到了什么样的速度改进,因为就用户的感知而言,我可能不会失去任何明显的保真度。谢谢。 【参考方案1】:当然,SSE 或 MMX 是可能的。
但是,在您的情况下,如果您使用方程式预先计算 256 个条目表,您可能会获得几乎相同的速度提升。
然后用简单的表查找替换所有计算。我最好的选择是,在现代处理器上,这将提供与 MMX/SSE 几乎相同的速度。
【讨论】:
我想了一下,想确保我理解你。要完全预先计算一个表,如果我将compressionRatio 和 shiftValue 重铸为 Byte 并按 (p0^, compressionRatio, shiftValue) 对表进行索引,则需要一个 256 立方或 16,777,216 字节大小的 3 维表,该表非常大。还是您表示的是不同的表示? 不,我们的想法是在像素上的循环之外计算表格 @RobertOschler,只需预先计算乘法即可开始。这将摆脱每像素 3 次乘法和 3 次代价高昂的 Trunc()。我怀疑预先计算添加 shiftVal 会为您节省很多。以上是关于这个 Delphi 6 位图修改代码可以用 SIMD 或其他方法加速吗?的主要内容,如果未能解决你的问题,请参考以下文章
Delphi资源文件(全面分析之位图光标图标AVIJPEGWave)