在OpenMP中,c++动态内存分配较慢,即使对于代码的非并行部分也是如此

C++ dynamic memory allocation is slower in OpenMP, even for non-parallel sections of code

本文关键字:并行部 代码 动态 内存 c++ OpenMP 分配 于代码      更新时间:2023-10-16

我遇到了一个相当令人沮丧的OpenMP问题:似乎如果OpenMP在代码中的某个地方以并行模式使用(用于多个线程),那么动态内存分配/取消分配即使在代码的非并行部分也会变慢。下面是一个示例程序(只是一个说明):

int main()
{
    #pragma omp parallel
    {
        // Just to get OpenMP going
    }
    double wtime0, wtime;
    wtime0 = omp_get_wtime();
    double **stuff;
    const int N = 1000000;
    stuff = new double*[N];
    for (int i=0; i < N; i++) stuff[i] = new double;
    for (int i=0; i < N; i++) *(stuff[i]) = sqrt(i);
    for (int i=0; i < N; i++) delete[] stuff[i];
    delete[] stuff;
    wtime = omp_get_wtime() - wtime0;
    cout << "Total CPU time: " << wtime << endl;
}

当我在我的笔记本电脑(这是一个Intel Core 2 Duo)上用一个线程运行这段代码时,我得到的CPU时间为0.093。另一方面,如果我用两个线程运行它,CPU时间增加到0.13。指针分配越多,差异就越严重。在上面的代码中,如果我用一个简单的数组替换"stuff",例如

    double stuff2[N];
    for (int i=0; i < N; i++) stuff2[i] = sqrt(i);

则没有差异。有人能告诉我为什么这个问题存在当指针分配/取消分配,即使它不是并行完成?这是一个问题的原因是因为在我正在使用的实际代码中,动态内存分配是必不可少的。有些部分可以通过并行运行来加快速度,但是(两个线程相对于一个线程)内存分配/取消分配的速度会大大减慢,即使在非并行部分中也是如此。如果有一个有丰富OpenMP经验的人能告诉我如何解决这个问题,我将非常感激。(最坏的情况下,我可以使用MPI代替,但我希望它可以在OpenMP中解决。)

提前感谢您的帮助。

是的,这是可以理解的。一般来说,在多线程环境中应该避免幼稚的动态分配,因为那里只有一个锁。支持mt的分配器提供了更好的性能,在分配较多的场景中应该是首选。这就是为什么我总是讨厌这里的代码,这些代码只使用向量、字符串或共享指针作为类成员,而不让用户指定分配策略。