这个 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)

太有用了,所以转:Delphi下16进制位图数据转位图

delphi处理jpeg问题

Delphi GDI对象之脱屏位图(Offscreen Bitmaps),也叫内存位图

易语言这个DLL代码怎么用delphi写?

Delphi GDI对象之绘制位图