优化ARM的扫描线转换功能

时间:2013-07-27 05:03:08

标签: arm neon directxmath

下面的代码将一行从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);
  }
}

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分: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);
  }
}