以下c ++程序是否有任何代码优化方法

时间:2011-03-14 05:19:32

标签: c++ optimization loops for-loop

        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;
            }
        }

5 个答案:

答案 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;

您还应该将srcDatapData声明为BYTE * restrict指针,以便编译器知道它们不是别名。

答案 1 :(得分:0)

我没有看到你做的那些没有必要。您可以将后增量更改为预增量(例如idx++++idx),但这不会产生可测量的效果。

此外,您可以使用std::copy代替memcpystd::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;
    }
}
相关问题