1

是否可以使用 memcpy 的某些功能从 1D 数组复制到 3D?

现在我正在使用一种缓慢的方法:

for(int loop1 = 0; loop1 < numberAgents; loop1++)
    for(int loop2 = 0; loop2 < fieldWidth; loop2++)
        for(int loop3 = 0; loop3 < fieldWidth; loop3++)
            potentialField[loop1][loop2][loop3] = cpuPotentialField[loop1 * fieldWidth * fieldWidth + loop2 * fieldWidth + loop3];

这不起作用:

memPotentialField = numberAgents * fieldWidth * fieldWidth * sizeof(float);
memcpy(potentialField, cpuPotentialField, memPotentialField);
4

3 回答 3

3

多维数组按行存储(第 8.3.4/9 节),所以基本上你的方法memcpy很好(因为浮点数是 POD)。

memcpy(&potentialField[0][0][0], cpuPotentialField,
       sizeof(potentialField)/sizeof(***potentialField));

使用 std::copy 更好,因为它也适用于非 PODS。所以我会写

std::copy(&potentialField[0][0][0],
          &potentialField[0][0][0] + sizeof(potentialField)/sizeof(potentialField[0][0][0]),
          cpuPotentialField);
于 2012-11-25T22:27:29.107 回答
1

除非你有一个特别糟糕的编译器或者你忘记开启优化(例如-O3),那么第一种方法在性能方面应该很好。但是,您可以通过提升一些乘法来对其进行一些优化:

for (int loop1 = 0; loop1 < numberAgents; loop1++)
{
    const int index1 = loop1 * fieldWidth * fieldwidth;

    for (int loop2 = 0; loop2 < fieldWidth; loop2++)
    {
        const int index2 = index1 + loop2 * fieldWidth;

        for (int loop3 = 0; loop3 < fieldWidth; loop3++)
        {
            potentialField[loop1][loop2][loop3] = cpuPotentialField[index2 + loop3];
        }
    }
}
于 2012-11-25T22:14:29.603 回答
0

您可以通过展开循环获得一些性能。在某些处理器中,分支或跳转指令会导致指令流水线重新加载,从而浪费时间。

//...
unsigned int items_remaining = fieldWidth;
for (unsigned int loop3 = 0; loop3 < fieldWidth; ++loop3)
{
    unsigned int copy_count = 4 - (items_remaining % 4);
    switch (copy_count)
    {
        // The fall-through of these cases is intentional.
        case 4:
          potentialField[loop1][loop2][loop3] = cpuPotentialField[loop1 * fieldWidth * fieldWidth + loop2 * fieldWidth + loop3];
          ++loop3;
          --items_remaining;
        case 3:
          potentialField[loop1][loop2][loop3] = cpuPotentialField[loop1 * fieldWidth * fieldWidth + loop2 * fieldWidth + loop3];
          ++loop3;
          --items_remaining;
        case 2:
          potentialField[loop1][loop2][loop3] = cpuPotentialField[loop1 * fieldWidth * fieldWidth + loop2 * fieldWidth + loop3];
          ++loop3;
          --items_remaining;
        case 1:
          potentialField[loop1][loop2][loop3] = cpuPotentialField[loop1 * fieldWidth * fieldWidth + loop2 * fieldWidth + loop3];
          ++loop3;
          --items_remaining;
    } // End: switch
} // End: for  

这仅针对 4 个项目展开。循环中的项目越多,循环的效率就越高。正如 Paul R 所说,预先计算一些索引也会有所帮助。

某些处理器可能具有编译器可以利用的专用复制指令,具体取决于编译器。

于 2012-11-25T22:47:10.780 回答