让我们从这里开始:
我有一个 16 字节的内存块,我只需要将偶数字节复制到一个 8 字节的内存块。
我目前的算法是这样的:
unsigned int source_size = 16, destination_size = 8, i;
unsigned char * source = new unsigned char[source_size];
unsigned char * destination = new unsigned char[destination_size];
// fill source
for( i = 0; i < source_size; ++i)
{
source[i] = 0xf + i;
}
// source :
// 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e
// copy
for( i = 0; i < destination_size; ++i)
{
destination[i] = source[i * 2];
}
// destination :
// 0f 11 13 15 17 19 1b 1d
这只是一个示例,因为我想知道当我需要获取每第 3 个字节或每第 4 个字节时是否有更好的方法来执行此操作,而不仅仅是偶数个字节。
我知道使用循环我可以实现这个但我需要优化这个...我不完全知道如何使用 SSE 所以我不知道在这种情况下是否可以使用,但是像 memcpy magic有点事情会很棒。
我还考虑过使用宏来摆脱循环,因为源和目标的大小都是恒定的,但这看起来没什么大不了的。
如果我说这是提取 YUYV 像素格式的 YCbCr 字节,您可能会跳出框框。另外我需要强调的是,我这样做是为了摆脱 libswscale。
最佳答案
虽然我怀疑编译器和 cpu 在这种情况下已经做得很好;如果您真的想要替代方案,请研究一下反转莫顿数的技术。这个问题How to de-interleave bits (UnMortonizing?)展示了如何在位上执行此操作,但这个想法也可以扩展到字节。
类似的东西(仅作为示例,这不是生产质量)
// assuming destination is already zero...
For (int i=0; i < destination_size; i += 2) {
long* pS = (long*) &source[ i * 2 ];
long* pD = (long*) &destination[ i ];
long a = *pS &0xff00ff00;
*pD |= *pS | ( *pS << 8 );
}
这是否比您的版本快取决于确切的 cpu 类型和编译器生成的内容。即测试并查看哪个更快,正如其他人所提到的,内存获取瓶颈将掩盖给定小数组的所有内容。
关于c++ - 如何使用模式从内存中复制字节(YUYV 打包到 YUV420 平面),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30236544/