我目前正在开发ios上的绘画应用程序。
我使用直接绘制到NSMutableData缓冲区并使用我的画笔应用混合:
- (void) combineColorDestination:(unsigned char*) dest source:(unsigned char*) src
{
const unsigned char sra = ((unsigned char *)src)[3];
const float oneminusalpha = 1.0f - (sra / 255.f);
int d[4];
for (int i=0;i<4;i++)
{
d[i] = oneminusalpha * ((unsigned char *)dest)[i] + ((unsigned char *)src)[i];
if (d[i]>255)
d[i] = 255;
((unsigned char *)dest)[i] = (unsigned char)d[i];
}
}
有任何优化建议吗?
我之前尝试使用霓虹灯,但我有一个我无法修复的错误(边界像素是错误的)
我像这样迭代像素2:
uint8x8_t va = vld1_u8(dest);
uint8x8_t vb = vld1_u8(src);
uint8x8_t res = vqadd_u8(va,vb);
vst1_u8(dest, res);
答案 0 :(得分:2)
连连呢?好的。请注意,无论您正在进行哪种多媒体操作,这些都是有效的,并且几乎不受您的情况限制。
首先,在你做NEON之前,你应该改变你的代码,让一个函数同时改变一堆像素(至少一行,一个矩形,如果你可以),而不是一个函数(或方法 - 甚至更糟糕的是,它改变了一个像素,被称为一堆像素:不知怎的,我怀疑画笔只有1x1像素。
其次,除了列循环(和最终的行循环)之外,应该没有分支(即流控制结构)。否for (i=0;i<4;i++)
;只需按顺序编写四个通道的代码(必要时使用宏)。否if (d[i]>255)
;表示作为替代:dest[i] = (temp>255?255:temp);
至少,如果没有用更有效的方式替换它来进行饱和(使用减法,移位和掩码的技巧)。
第三,避免浮点数和整数之间的任何转换;这总是有效的建议,但float-&gt; int转换对ARM特别具有破坏性。由于你在操纵整数,这意味着在这里有浮点数。
一旦你做到了这一点,就会感到惊讶,除了让你的代码更快,你实际上已经完成了NEON的准备工作:如果你一次处理一堆像素,如果没有分支,NEON只是远程有用的,如果你不在整个地方之间转换浮点数和整数。所以,只有这样,我们才能谈论NEON,如果在这一点上甚至是必要的话。