使用openmp在C中进行并行编程

时间:2021-02-05 13:53:53

Right now I am learning about parallel programming in C with openmp and now I have stumbled upon the following problem. I have a simple for loop which I want to parallelize. Using openmp, I thought the following code should do the job

现在我正在学习使用openmp在C中进行并行编程,现在我偶然发现了以下问题。我有一个简单的for循环,我想并行化。使用openmp,我认为以下代码应该可以完成这项工作

unsigned long int teller_groot;
int               boel = 0;
int               k    = 0; 
int               l    = 1;
unsigned long int sum2;
int               thread_id;
int               nloops;

#pragma omp parallel private(thread_id, nloops)
{   
    sum2 = 0;
    #pragma omp for
        for (teller_groot=1000000; teller_groot<1000000000000; teller_groot++)
        {
            boel = 0;
            for (int i = 0; i < 78498; i++)
            {
                if (floor(teller_groot / array[i]) == teller_groot / array[i])                    
                {
                   boel = 1; 
                   break;
                }
            }

            if (boel == 0)
            {
               sum2 = sum2 + teller_groot;
            }

            if (sum2 >= 1000000000)
            {
               sum2 = sum2 - 1000000000;
            }

            if (k == 10000000)
            {
               printf("%d, ", l);
               l++;
               k = 0;
            }

            k++;
        }

        thread_id = omp_get_thread_num();

        printf("Thread %d performed %d iterations of the loop.\n", thread_id, nloops);
}

The code

代码

if (k == 10000000)
{
    printf("%d, ",l);
    l++;
    k = 0;
}

k++;

is just for me to know how far in the loop we are. If I run the program, it doesn't print anything, meaning it does not calculate anything. What is wrong with the code then? Thanks.

只是让我知道我们在循环中有多远。如果我运行该程序,它不会打印任何内容,这意味着它不会计算任何内容。那么代码有什么问题呢?谢谢。

2 个解决方案

#1


1  

You have declared the variable k (among others) outside the openmp for loop. When variables are declared outside parallel regions they have shared scope by default. This means all of the threads you use will be checking and writing to the same k variable, which could result in race conditions.

你已经在openmp for循环之外声明了变量k(以及其他)。当变量在并行区域之外声明时,它们默认具有共享范围。这意味着您使用的所有线程都将检查并写入相同的k变量,这可能会导致竞争条件。

If you want to write to the same variable k with different threads you could use locks or atomic updates to produce the behaviour you want.

如果要使用不同的线程写入相同的变量k,可以使用锁或原子更新来生成所需的行为。

Otherwise, declare k as a private variable in the #pragma statement at the beginning of the parallel region:

否则,在并行区域开头的#pragma语句中将k声明为私有变量:

#pragma omp parallel private(thread_id, nloops, k)

A good primer is available here: http://supercomputingblog.com/openmp/tutorial-parallel-for-loops-with-openmp/

这里有一本很好的入门书:http://supercomputingblog.com/openmp/tutorial-parallel-for-loops-with-openmp/

#2


1  

I don't have enough reputation to comment, so I'm writing an answer.

我没有足够的声誉来发表评论,所以我正在写一个答案。

Which part of your code exactly gets stuck? (by stuck do we mean it takes an awful lot of time?)

代码的哪一部分完全卡住了? (卡住了,我们是说需要花费大量的时间吗?)

because:

因为:

            if (floor(teller_groot / array[i]) == teller_groot / array[i])                    
            {
               boel = 1; 
               break;
            }

What you do is floor the result of (lets say to make it simple) 22/41 = 0.536 to => 0.5 and then check whether 0.536 == 0.5 and this does not equal so the command break might not get executed, depending on what is in array which you have not specified.

你做的是把结果(让我们说简单)22/41 = 0.536到=> 0.5然后检查是否0.536 == 0.5并且这不相等所以命令中断可能不会被执行,这取决于什么是在您未指定的数组中。

Also, a lot of your variables are shared including array, that might make a difference as well and the variable nloops is not specified (unless somewhere above the code you've shown)

此外,您的许多变量都是共享的,包括数组,这也可能会产生影响,并且未指定变量nloops(除非您显示的代码上方某处)

check this pdf about openmp: http://openmp.org/mp-documents/OpenMP4.0.0.Examples.pdf

查看这个关于openmp的pdf:http://openmp.org/mp-documents/OpenMP4.0.0.Examples.pdf

EDIT: btw, try flushing the buffer after printf(): fflush(stdout)

编辑:顺便说一下,尝试在printf()后刷新缓冲区:fflush(stdout)

#1


1  

You have declared the variable k (among others) outside the openmp for loop. When variables are declared outside parallel regions they have shared scope by default. This means all of the threads you use will be checking and writing to the same k variable, which could result in race conditions.

你已经在openmp for循环之外声明了变量k(以及其他)。当变量在并行区域之外声明时,它们默认具有共享范围。这意味着您使用的所有线程都将检查并写入相同的k变量,这可能会导致竞争条件。

If you want to write to the same variable k with different threads you could use locks or atomic updates to produce the behaviour you want.

如果要使用不同的线程写入相同的变量k,可以使用锁或原子更新来生成所需的行为。

Otherwise, declare k as a private variable in the #pragma statement at the beginning of the parallel region:

否则,在并行区域开头的#pragma语句中将k声明为私有变量:

#pragma omp parallel private(thread_id, nloops, k)

A good primer is available here: http://supercomputingblog.com/openmp/tutorial-parallel-for-loops-with-openmp/

这里有一本很好的入门书:http://supercomputingblog.com/openmp/tutorial-parallel-for-loops-with-openmp/

#2


1  

I don't have enough reputation to comment, so I'm writing an answer.

我没有足够的声誉来发表评论,所以我正在写一个答案。

Which part of your code exactly gets stuck? (by stuck do we mean it takes an awful lot of time?)

代码的哪一部分完全卡住了? (卡住了,我们是说需要花费大量的时间吗?)

because:

因为:

            if (floor(teller_groot / array[i]) == teller_groot / array[i])                    
            {
               boel = 1; 
               break;
            }

What you do is floor the result of (lets say to make it simple) 22/41 = 0.536 to => 0.5 and then check whether 0.536 == 0.5 and this does not equal so the command break might not get executed, depending on what is in array which you have not specified.

你做的是把结果(让我们说简单)22/41 = 0.536到=> 0.5然后检查是否0.536 == 0.5并且这不相等所以命令中断可能不会被执行,这取决于什么是在您未指定的数组中。

Also, a lot of your variables are shared including array, that might make a difference as well and the variable nloops is not specified (unless somewhere above the code you've shown)

此外,您的许多变量都是共享的,包括数组,这也可能会产生影响,并且未指定变量nloops(除非您显示的代码上方某处)

check this pdf about openmp: http://openmp.org/mp-documents/OpenMP4.0.0.Examples.pdf

查看这个关于openmp的pdf:http://openmp.org/mp-documents/OpenMP4.0.0.Examples.pdf

EDIT: btw, try flushing the buffer after printf(): fflush(stdout)

编辑:顺便说一下,尝试在printf()后刷新缓冲区:fflush(stdout)