BYTE * srcData;
BYTE * pData;
int i,j;
int srcPadding;
//some variable initialization
for (int r = 0;r < h;r++,srcData+= srcPadding)
{
for (int col = 0;col < w;col++,pData += 4,srcData += 3)
{
memcpy(pData,srcData,3);
}
}
我已经尝试过循环展开,但它几乎没有帮助。
int segs = w / 4;
int remain = w - segs * 4;
for (int r = 0;r < h;r++,srcData+= srcPadding)
{
int idx = 0;
for (idx = 0;idx < segs;idx++,pData += 16,srcData += 12)
{
memcpy(pData,srcData,3);
*(pData + 3) = 0xFF;
memcpy(pData + 4,srcData + 3,3);
*(pData + 7) = 0xFF;
memcpy(pData + 8,srcData + 6,3);
*(pData + 11) = 0xFF;
memcpy(pData + 12,srcData + 9,3);
*(pData + 15) = 0xFF;
}
for (idx = 0;idx < remain;idx++,pData += 4,srcData += 3)
{
memcpy(pData,srcData,3);
*(pData + 3) = 0xFF;
}
}
答案 0 :(得分:1)
根据您的编译器,您可能根本不需要memcpy
这么小的副本。这是展开循环体的变体版本;看看它是否更快:
uint32_t in0 = *(uint32_t*)(srcData);
uint32_t in1 = *(uint32_t*)(srcData + 4);
uint32_t in2 = *(uint32_t*)(srcData + 8);
uint32_t out0 = UINT32_C(0xFF000000) | (in0 & UINT32_C(0x00FFFFFF));
uint32_t out1 = UINT32_C(0xFF000000) | (in0 >> 24) | ((in1 & 0xFFFF) << 8);
uint32_t out2 = UINT32_C(0xFF000000) | (in1 >> 16) | ((in2 & 0xFF) << 16);
uint32_t out3 = UINT32_C(0xFF000000) | (in2 >> 8);
*(uint32_t*)(pData) = out0;
*(uint32_t*)(pData + 4) = out1;
*(uint32_t*)(pData + 8) = out2;
*(uint32_t*)(pData + 12) = out3;
您还应该将srcData
和pData
声明为BYTE * restrict
指针,以便编译器知道它们不是别名。
答案 1 :(得分:0)
我没有看到你做的那些没有必要。您可以将后增量更改为预增量(例如idx++
到++idx
),但这不会产生可测量的效果。
此外,您可以使用std::copy
代替memcpy
。 std::copy
提供了更多信息,理论上可以选择最有效的方法来复制内容。不幸的是,我不相信许多STL实现实际上利用了额外的信息。
我唯一期望会产生影响的是,在开始下一个memcpy
之前没有理由等待{{1}}完成。您可以使用OpenMP或英特尔线程构建模块(或某种线程队列)来并行化循环。
答案 2 :(得分:0)
不要调用memcpy,只需手动复制即可。除非你一次可以复制超过3个字节,否则函数调用开销是不值得的。
答案 3 :(得分:0)
就这个特定的循环而言,你可能想看一个名为Duff's device的技术,这是一种利用switch结构的循环展开技术。
答案 4 :(得分:0)
可能更改为while循环而不是嵌套for循环:
BYTE *src = srcData;
BYTE *dest = pData;
int maxsrc = h*(w*3+srcPadding);
int offset = 0;
int maxoffset = w*3;
while (src+offset < maxsrc) {
*dest++ = *(src+offset++);
*dest++ = *(src+offset++);
*dest++ = *(src+offset++);
dest++;
if (offset > maxoffset) {
src += srcPadding;
offset = 0;
}
}