2013-11-26 52 views
1

我优化了使用OpenMP循环。在每个线程中,一个大数组将被临时使用(当这个线程完成时不需要)。由于我不想重复分配&删除这些数组,所以我打算分配一大块内存,并为每个线程分配一部分。为避免冲突,我应该为每个正在运行的线程设置一个唯一的ID,该ID不应该改变,并且不能等于另一个线程。所以我的问题是,我可以通过函数omp_get_thread_num()为此使用线程ID返回吗?或者是否有任何有效的解决方案用于这种内存分配&分配任务?非常感谢!内存分配和分配在C++中使用OpenMP

+3

是的,可以。 omp_get_thread_num()返回不会改变的唯一线程ID,通常使用线程ID来分割矩阵/数组 –

+0

Cool!非常感谢! –

+0

您是否需要该内存才能在多个入口之间保持同一平行区域或连续并行区域?前一种情况的一个例子是具有平行内环的串行外环。同样由'omp_get_thread_num()'**返回相同的线程ID并不一定表示代码正在被同一进程线程执行。 –

回答

0

一旦你的程序遇到并行区域,即一旦它击中

#pragma omp parallel 

线程(可能在程序初始化或直到第一个并行构造已启动)将被激活。在并行区域内,任何分配内存的线程,例如数组,都将在它自己的私有地址空间内分配内存。除非线程解除分配内存,否则它将保持分配给整个并行区域。

如果您的程序首先以串行方式为阵列分配内存,然后在进入并行区域时将该阵列复制到所有线程,请使用firstprivate子句并让运行时间负责将阵列复制到每个线程的私有地址空间。

鉴于所有这一切,我没有看到分配的点,大概在遇到并行区域之前,大量的内存然后使用一些自己的方法在线程之间共享它,以基于计算线程ID。

+0

谢谢。我的目的是为了避免在线程中分配内存的开销。假设线程大小为8,并且每个线程都需要内存大小N,所以我只需要分配N * 8内存,并让每个线程拥有唯一的大小为N的私有部分。是的,我可以用firstprivate子句复制数组的指针,但是这不知道当前线程没有使用哪个部分。 –

+1

啊,所以你宁愿有一个线程分配'8n'字节,而不是'8'线程分配'n'字节。我不确定我认为这不仅仅是一种不必要的优化 - 并且让我相信,你不必向我展示数据。至于指针,你把他们带入讨论中,而不是我。 –

+0

其实,我想在开始的时候,而不是每个线程分配8N分配N,总的螺纹尺寸远远超过8个,但正处在同时运行最多8个线程。 –

2

可以启动并行段,然后开始分配变量/记忆。在并行部分中声明的所有内容在其自己的堆栈上都是线程私有的。例如:

#pragma omp parallel 
{ 
    // every variable declared here is thread private 
    int * temp_array_pointer = calloc(sizeof(int), num_elements); 
    int temp_array_on_stack[num_elements]; 

    #pragma omp for 
    for (...) { 
     // whatever my loop does 
    } 

    // if you used dynamic allocation 
    free(temp_array_pointer); 
} 
+0

你如何建议在这里做错误处理?任何calloc调用都可能失败。 IMO更容易在程序启动时分配临时结构,以便更轻松地处理错误。 – pburka

+2

@pburka如果你使用自动变量(堆栈分配),那么你不需要错误处理。如果你在并行部分执行'* alloc',那么你应该在这里进行错误处理。我建议在parallel部分中分配所有线程专用的内容,以便1)避免任何潜在的错误,并在指针周围传递2)如果你在NUMA机器上工作,那么这将允许你分配内存硬件本地执行线程,从而提高性能。 –

+0

如果使用大自动变量,那么应该熟悉'ulimit -s'(Un * x)/'/ STACK:nnn'(Windows)和'OMP_STACKSIZE'。 –