下面的代码将一行从8位格式化的格式转换为32-RGBA。
在我尝试实现它之前,我想知道下面的代码是否适合使用Direct-Math或ARM 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);
}
}
答案 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);
}
}