【发布时间】:2021-04-07 04:51:20
【问题描述】:
我想让 2 个线程组同时运行。例如,2 个线程正在执行代码块 1,另外 2 个线程正在执行另一个代码段。 OpenMP: Divide all the threads into different groups 这里有一个 stackoverflow 问题,我更改了代码以查看它是否适合我在代码中需要的逻辑。
我有下面的代码。
#include <stdio.h>
#include <omp.h>
#define NUM_THREADS 1
int main(int argc, char **argv) {
omp_set_nested(1); /* make sure nested parallism is on */
int nprocs = omp_get_num_procs();
int nthreads1 = NUM_THREADS;
int nthreads2 = NUM_THREADS;
int t1[nthreads1];
for (int i=0; i<nthreads1; i++) {
t1[i] = 0;
}
#pragma omp parallel default(none) shared(nthreads1, nthreads2, t1) num_threads(2)
#pragma omp single
{
#pragma omp task // section 1
#pragma omp parallel for num_threads(nthreads1) shared(t1)
for (int i=0; i<nthreads1; i++) {
printf("Task 1: thread %d of the %d children of %d: handling iter %d\n",
omp_get_thread_num(), omp_get_team_size(2),
omp_get_ancestor_thread_num(1), i);
t1[i] = 1;
}
#pragma omp task // section 2
#pragma omp parallel for num_threads(nthreads2) shared(t1, t2)
for (int j=0; j<nthreads2; j++) {
while (!t1[j]) {
printf("Task 2: thread %d of the %d children of %d: handling iter %d\n",
omp_get_thread_num(), omp_get_team_size(2),
omp_get_ancestor_thread_num(1), j);
}
}
}
return 0;
}
为了检查我的代码是否同时运行 2 个线程组,我将每个组中的线程计数设置为 1,然后保留一个初始化为 0 的布尔列表。 在第一个代码段中,我将布尔值设置为 1,在第二个代码段中,我检查布尔值以跳出 while 循环。上面的代码似乎只由 1 个线程运行,因为如果线程开始运行第二个代码块/部分,那么它会一直卡在 while 循环中,因为另一个线程没有将布尔值设置为 1。
如何并行运行 2 个线程组?
更新:我的用例:我正在使用 OpenMP 编写一个字数统计映射减少程序。我想要一个线程组 2 读取文件,它将读取行添加到队列中。我想要另一个线程组来处理这些队列中的行并更新链式哈希表中的计数。我已经编写了代码,首先进行读取以制定队列,然后进行映射以从队列中获取数据并生成字数 - 但我想将我的程序更改为有 2 个线程组来并行读取和映射 - - 同时。这就是为什么我制作这个短代码来检查我如何实现 2 个线程组,并行运行执行 2 个不同的代码段。
【问题讨论】:
-
不管代码的其余部分如何,这里缺少的是一些
#pragma omp flush指令。只需在第二部分的t1[i] = 1;行之后添加一个,然后在printf()之后添加另一个... -
除了 Gilles 的评论之外,您还可以使用原子指令(或代价高昂的关键部分)。在现代架构上使用缓存使变量在线程之间保持一致。但是缓存或不同的核心并不总是完全同步,因为这很昂贵。因此,您需要告诉您的处理器您在线程之间执行一些手动通信/同步,以便它可以在内核之间同步变量的值。
-
你是说上面的代码并行运行2个线程做不同的工作? @吉尔斯?我添加了
#pragma omp flush directive,但它似乎不起作用。 -
因为我在声明#pragma omp 指令时使用的是shared(t1)。在这种情况下,同步真的很重要吗?我的意思是,如果一个线程将布尔值设置为 1,那么另一个线程应该能够跳出 while 循环,对吗?似乎一次只运行一个线程。 @JérômeRichard
-
是的,同步很重要。您不应假设线程具有内存的同步视图,因为在某些平台上,一个线程可以更改共享变量,而其他线程看不到修改。我无法在我的机器上重现该问题。所以这个问题很可能是平台相关的(这与前面的消息是一致的)。您能否在问题中添加有关您的平台(处理器、系统、编译器等)的信息以及输出示例?除此之外,在这种情况下,您可以尝试使用 OpenMP 部分而不是任务。
标签: c multithreading parallel-processing openmp