我正在使用openMP优化一个for循环。在每个线程中,将会临时使用一个大数组(当该线程完成时不再需要)。由于我不想重复分配和删除这些数组,所以我计划分配一个大的内存块,并将其分配给每个线程的一部分。为了避免冲突,我应该为每个运行线程分配一个唯一的ID,该ID不应更改并且不能等于另一个线程。因此,我的问题是,我可以使用函数omp_get_thread_num()返回的线程ID来实现这个目的吗?或者是否有任何高效的解决方案来完成这样的内存分配和分配任务?非常感谢!
您可以开始并行部分,然后开始分配变量/内存。在并行部分内声明的所有内容都是线程私有的,存在自己的堆栈中。例如:
#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);
}
*alloc
,那么是的,您应该在此处进行错误处理。我建议在并行部分内分配所有线程私有的内容,以避免传递指针时出现任何潜在的错误,并且如果您正在使用NUMA机器,则这将允许您将内存硬件本地化到执行线程,从而提高性能。 - Sergey L.ulimit -s
(Un*x)/ /STACK:nnn
(Windows)和 OMP_STACKSIZE
。 - Hristo Iliev一旦您的程序遇到并行区域,也就是一旦它触发了
#pragma omp parallel
线程(可能已在程序初始化时启动,也可能直到第一个并行构造才启动)将变为活动状态。在并行区域内,分配内存的任何线程(例如,分配给数组)都将在其自己的私有地址空间中分配该内存。除非线程释放内存,否则它将保留整个并行区域的内存。
如果您的程序首先在串行模式下为数组分配内存,然后在进入并行区域时将该数组复制到所有线程中,请使用firstprivate
子句,并让运行时处理将数组复制到每个线程的私有地址空间中。
考虑到这一切,我不明白在遇到并行区域之前,为什么要分配大量内存,然后使用基于线程ID的计算来分割内存,以便在线程之间共享。
8n
字节而不是让8
个线程分别分配n
字节。我不确定这是否只是一种不必要的优化 - 要说服我这不是这样,你需要向我展示数据。至于指针,是你把它们带入了讨论,而不是我。 - High Performance Mark
omp_get_thread_num()
返回相同的线程 ID 并不一定意味着代码正在由同一进程线程执行。 - Hristo Iliev