C++ 在cpp中将一维阵列快速复制到三维阵列

C++ 在cpp中将一维阵列快速复制到三维阵列,c++,arrays,performance,3d,copy,C++,Arrays,Performance,3d,Copy,是否可以使用memcpy功能从一维阵列复制到三维阵列 现在我使用一种缓慢的方法: for(int loop1 = 0; loop1 < numberAgents; loop1++) for(int loop2 = 0; loop2 < fieldWidth; loop2++) for(int loop3 = 0; loop3 < fieldWidth; loop3++) potentialField[loop1][loop2][l

是否可以使用memcpy功能从一维阵列复制到三维阵列

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

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

除非您有一个特别糟糕的编译器,或者您忘记启用优化(例如,
-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];
        }
    }
}
for(int-loop1=0;loop1
除非你有一个特别糟糕的编译器或者你忘记打开优化(例如,
-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];
        }
    }
}
for(int-loop1=0;loop1
多维数组是按行存储的(§8.3.4/9),因此基本上您使用
memcpy
的方法是好的(因为浮点数是POD)

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

std::copy(&potentialField[0][0][0],
          &potentialField[0][0][0] + sizeof(potentialField)/sizeof(potentialField[0][0][0]),
          cpuPotentialField);

多维数组是按行存储的(§8.3.4/9),因此基本上您使用
memcpy
的方法是很好的(因为浮点数是POD)

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

std::copy(&potentialField[0][0][0],
          &potentialField[0][0][0] + sizeof(potentialField)/sizeof(potentialField[0][0][0]),
          cpuPotentialField);

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

//...
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  
/。。。
未签名整数项\u剩余=字段宽度;
for(无符号整数loop3=0;loop3
这仅对4个项目展开。循环中的项目越多,循环的效率就越高。正如Paul R所说,预先计算一些指数也会有所帮助


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

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

//...
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  
/。。。
未签名整数项\u剩余=字段宽度;
for(无符号整数loop3=0;loop3
这仅对4个项目展开。循环中的项目越多,循环的效率就越高。正如Paul R所说,预先计算一些指数也会有所帮助


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

是什么让你认为你的第一个(工作)方法是“慢的”?你的函数可能是好的,或者是低效的,这取决于你的内存布局和数据的大小。能否提供
电位场
cpuPotentialField
的详细信息?它们真的是简单的数组吗?是什么让你认为你的第一个(工作)方法是“慢的”?你的函数可能是好的,或者是低效的,这取决于你的内存布局和数据的大小。能否提供
电位场
cpuPotentialField
的详细信息?它们真的是简单的数组吗?你的
std::copy
示例从3D复制到1D数组,不是与@Houp想要的相反吗?你的
std::copy
示例从3D复制到1D数组,不是与@Houp想要的相反吗?