-1

我有一段 C 代码正在尝试优化,其中涉及将数组 a 设置为 b。我目前正在使用 memcpy 来实现这一点,它可以工作,但是速度不够快。IE

double a[4] = {1.0, 2.0, 3.0, 4.0};
double b[4];
memcpy(b, a, sizeof(a));

这是一个基本示例,我的程序类似,但最多使用 9000 个双打。我知道使用指针可以节省很多时间,但我不知道该怎么做。非常感谢您的帮助。

编辑:我不需要保留可以丢弃的 a 数组。我只需要从a转移到b。

4

2 回答 2

8

如果memcpy()不工作,你就卡住了。对于大型操作数,该memcpy()函数受内存限制,因此不可能*击败它。唯一的选择是重新设计您的程序,使其不需要复制数组。

(“内存绑定”是指memcpy()受限于 RAM 或内存控制器的速度。函数可以是 CPU 绑定、内存绑定、IO 绑定等)

在大多数平台上,memcpy()它是用手动调整的汇编语言编写的,并经过大量优化以利用各种处理器特性(如 SSE)。尝试使用多个内核是行不通的,因为即使您将工作分散到更多内核上,也不会将工作分散到更多 RAM 或更多内存控制器上。

脚注

*某些平台或工具链的memcpy().

于 2013-05-21T08:30:04.130 回答
3

我使用 b 中的值来确定 a 的新值。它通过一个while循环检查数据是否收敛。

在这种情况下,如果您来回切换数组,您可能能够避免任何复制,就像这样(与您编写的内容相反;根据需要进行调整):

double array1[SIZE], array2[SIZE];
double* a = array1, double* b = array2;
generate_initial_values(array1);

for (;;)
{
    // do either 
    memcpy(b, a, sizeof array1); // sizeof either array will do; *don't* use sizeof a or b, which is only the size of the pointer, not of the array
    update_values_in_b(b);

    // or, better:
    produce_modified_values_in_b_from_a(a, b);

    if (converged(a, b)) break;
    // switch arrays
    double* temp_ptr = a;
    a = b;
    b = temp_ptr;
}

如果这对你有用,第二种方式会更快。如果您必须使用 memcpy,您可以尝试使用非常快的 memcpy 进行图像处理?,但可能对您最好的方法是使用 memcpy 并将编译器的优化级别设置得尽可能高。确保你#include <string.h>和 memcpy 的 size 参数是编译时常量(它在上面),并查看生成的汇编代码以验证编译器是否内联副本。

编辑:等等,这是另一个想法,甚至不需要切换数组:

double a[SIZE], b[SIZE];
generate_initial_values(a);

for (;;)
{
    produce_modified_values_in_second_array_from_first(a, b);
    if (converged(a, b)) break;
    produce_modified_values_in_second_array_from_first(b, a);
    if (converged(b, a)) break;
}

当您退出循环时,您不知道哪个数组具有最新值,但如果它们已经收敛,您可能不在乎。如果你这样做了,你可以设置一个指向最新值的指针,或者使用一个函数:

void calling_function(void)
{
    ...
    double a[SIZE], b[SIZE];
    generate_initial_values(a);
    double* great_values = get_great_values(a, b); // returns either a or b
    ...
}

double* get_great_values(double* a1, double* a2)
{
    for (;;)
    {
        produce_modified_values_in_second_array_from_first(a1, a2);
        if (converged(a1, a2)) return a2;
        produce_modified_values_in_second_array_from_first(a2, a1);
        if (converged(a2, a1)) return a1;
    }
}
于 2013-05-21T08:47:52.093 回答