0

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

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

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);
  }
}
4

2 回答 2

3

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

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

于 2013-07-28T23:54:27.733 回答
1

我同意 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);
  }
}
于 2013-07-29T16:05:06.303 回答