在C中大步复制内存的最快方法?

12 c memory iphone stride

我正在尝试尽快从RGBA图像数据中复制1或2个颜色通道(这是我的代码中最慢的一部分,它会减慢整个应用程序的速度).是否有快速的复制方式?

数据简单地布局为RGBARGBARGBA等,我只需复制R值,或者只需复制RG值.

到目前为止我所拥有的大致是复制R值:

for(int i=0; i<dataSize; i++){
    dest[i] = source[i*4];
}
Run Code Online (Sandbox Code Playgroud)

对于RG值,我正在做:

for(int i=0; i<dataSize; i+=2){
    dest[i] = source[i*2];
    dest[i+1] = source[(i*2)+1];
}
Run Code Online (Sandbox Code Playgroud)

所有数据都是无符号的1字节值.有更快的方法吗?我已经部分展开了循环(每次迭代执行64个值 - 超出该值的微不足道的加速).平台是Armv7(iOS),因此使用NEON(SIMD)可能很有用,不幸的是我没有经验!

遗憾的是,更改数据是由opengl的readPixels()函数提供的,而iOS不支持L,LA,RG等读取,据我所知.

Rog*_*ger 5

如果你对iOS4及更高版本没问题,你可能会发现vDSP和加速框架很有用.查看有关经线速度的各种图像处理优度的文档.

#import <Accelerate/Accelerate.h>
Run Code Online (Sandbox Code Playgroud)

我不知道你接下来会做什么,但是如果你正在对图像数据进行任何形式的计算,并希望它以浮点形式,你可以使用vDSP_vfltu8将源字节数据的一个通道转换为单精度浮点数点这样使用一行(不包括内存管理);

vDSP_vfltu8(srcData+0,4,destinationAsFloatRed,1,numberOfPixels)
vDSP_vfltu8(srcData+1,4,destinationAsFloatGreen,1,numberOfPixels)
vDSP_vfltu8(srcData+2,4,destinationAsFloatBlue,1,numberOfPixels)
vDSP_vfltu8(srcData+3,4,destinationAsFloatAlpha,1,numberOfPixels)
Run Code Online (Sandbox Code Playgroud)

如果您需要从操纵的浮点数据创建一个图像,请使用vDSP_vfuxu8返回另一个方向 - 所以;

vDSP_vfixu8(destinationAsFloatRed,1,outputData+0,4,numberOfPixels);
vDSP_vfixu8(destinationAsFloatGreen,1,outputData+1,4,numberOfPixels);
vDSP_vfixu8(destinationAsFloatBlue,1,outputData+2,4,numberOfPixels);
vDSP_vfixu8(destinationAsFloatAlpha,1,outputData+3,4,numberOfPixels);
Run Code Online (Sandbox Code Playgroud)

显然,您可以使用上述技术处理1或2个通道.

文档非常复杂,但结果很好.


ysa*_*sap 2

根据编译的代码,您可能希望将乘法替换为 2,并添加第二个循环索引(调用它j并将其前进 4):

for(int i=0, j=0; i<dataSize; i+=2, j+=4){
    dest[$i] = source[$j];
    dest[$i+1] = source[$j+1];
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以将乘法替换为移位 1:

for(int i=0, j=0; i<dataSize; i+=2, j+=4){
    dest[$i] = source[$i<<1];
    dest[$i+1] = source[($i<<1)+1];
}
Run Code Online (Sandbox Code Playgroud)

  • 恕我直言,用移位代替乘法是个坏建议。这是编译器关心的问题。 (3认同)