【问题标题】:Optimizing a scanline conversion function for ARM优化 ARM 的扫描线转换函数
【发布时间】:2013-07-27 05:03:08
【问题描述】:

下面的代码将一行从 8 位调色板格式转换为 32-RGBA。

在尝试实现它之前,我想知道下面的代码是否适合使用Direct-MathARM Neon intrinsics 或内联汇编进行优化。我第一次看文档并没有发现任何涵盖表格查找部分的内容。

void CopyPixels(BYTE *pDst, BYTE *pSrc, int width,
  const BYTE mask, Color* pColorTable)
{
  if (width)
  {
    do
    {
      BYTE b = *pSrc++;
      if (b != mask)
      {
        // Translate to 32-bit RGB value if not masked
        const Color* pColor = pColorTable + b;
        pDst[0] = pColor->Blue;
        pDst[1] = pColor->Green;
        pDst[2] = pColor->Red;
        pDst[3] = 0xFF;
      }
      // Skip to next pixel
      pDst += 4;
    }
    while (--width);
  }
}

【问题讨论】:

  • 访问表只是一个内存操作。这取决于表格的格式。使用 NEON,您只需使用 vld。如果您需要重新订购,有很多选择。例如,Blog on re-arranging vectors.
  • 你知道彩色图中的内容吗?您可能会想出一个近似值来避免查找操作并在更短的时间内运行,但仅适用于已知地图。

标签: arm neon directxmath


【解决方案1】:

您需要一个大小为 256*4bytes = 1024bytes 的 LUT。 这种工作根本不适合 SIMD。 (除了英特尔新 Haswell 内核的 SSE 部分)

NEON 可以使用 VTBL 和 VTBX 处理最大 32 字节的 LUT,但它或多或少意味着与 CLZ 一起作为 Newton-Raphson 迭代的起始值。

【讨论】:

    【解决方案2】:

    我同意 Jake 的观点,这不是一个很大的矢量处理器问题,并且可能由 ARM 主管道更有效地处理。这并不意味着您不能通过汇编来优化它(而只是简单的 ARM v7)以获得显着改进的结果。

    特别是,一个简单的改进是构建您的查找表,以便它可以与字大小的副本一起使用。这将涉及确保 Color 结构遵循 32-RGBA 格式,包括将第 4 个 0xFF 作为查找的一部分,这样您就可以只复制一个单词。这可以显着提升性能,无需组装,因为它是一次内存提取,而不是 3 次(加上一个常量分配)。

    void CopyPixels(RGBA32Color *pDst, BYTE const *pSrc, int width,
      const BYTE mask, RGBA32Color const *pColorTable)
    {
      if (width)
      {
        do
        {
          BYTE b = *pSrc++;
          if (b != mask)
          {
            // Translate to 32-bit RGB value if not masked
            *pDst = pColorTable[b];
          }
          // Skip to next pixel
          pDst ++;
        }
        while (--width);
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多