OpenMP性能与不同版本的操作系统的差异

时间:2013-04-11 19:16:22

标签: c performance openmp

我有一段代码,我刚才写的。它的唯一目的是使用openMP进行实验。但我最近将MacBook Pro Lion(2011年初)改为MacBook Pro Mountain Lion(2013年初)。如果它有助于获得更多硬件的其他信息,我很乐意给他们。 代码在旧代码上运行良好,这意味着8个线程在我的处理器上获得了100%(98%min)的负载。现在,在我的新机器上重新编译的相同代码仅获得62%的最大处理器负载。即使我提高线程。处理器负载均使用“istat pro”进行测量。

我的问题是什么导致这种情况发生?

编辑:如果我删除#pragma omp parallel for shared(largest_factor, largest)中的for,问题似乎就解决了。所以我得到#pragma omp parallel shared(largest_factor, largest) 但我仍然不明白它为什么会起作用。

有问题的代码:

#include <stdio.h>
#include <omp.h>

double fib(double n);

int main()
{
    int data[] = {124847,194747,194747,194747,194747,
                  194747,194747,194747,194747,194747,194747};
    int largest, largest_factor = 0;



    omp_set_num_threads(8);
    /* "omp parallel for" turns the for loop multithreaded by making each thread
     * iterating only a part of the loop variable, in this case i; variables declared
     * as "shared" will be implicitly locked on access
     */
    #pragma omp parallel for shared(largest_factor, largest)
    for (int i = 0; i < 10; i++) {
            int p, n = data[i];

            for (p = 3; p * p <= n && n % p; p += 2);
            printf("\n%f\n\n",fib(i+40));
            if (p * p > n) p = n;
            if (p > largest_factor) {
                    largest_factor = p;
                    largest = n;
                    printf("thread %d: found larger: %d of %d\n", 
                            omp_get_thread_num(), p, n);
            } 
            else 
            {
                    printf("thread %d: not larger:   %d of %d\n", 
                           omp_get_thread_num(),     p, n);
            }
    }

    printf("Largest factor: %d of %d\n", largest_factor, largest);
    return 0;
} 

double fib(double n)
{ 
if (n<=1)
{
    return 1;
}
else
{
    return fib(n-1)+fib(n-2);
}
}

1 个答案:

答案 0 :(得分:0)

您没有看到所有线程被使用的主要原因是每个线程占用不同的时间(由于递归函数或内部循环),并且您只有10次迭代。快速线程快速完成,然后只剩下几个线程运行。当您第一次运行代码时,它会以100%的速度启动,并在快速线程完成且最后一些慢速线程仍在运行时脱落。如果将迭代次数更改为100(并增加数据数组),则CPU使用率将持续100%。我在你的代码中添加了一些计时打印输出。

此外,我认为你的共享变量存在竞争条件,所以我放入一个关键部分。

要回答关于没有“for”语句的代码的问题,我们正在做的是在八个不同的线程上运行相同的代码!它们不是运行特定迭代的线程,而是运行所有10次迭代。这不会比运行单个线程更快,甚至可能更慢。

最后,由于每次迭代通常需要不同的时间,所以你应该像这样使用“schedual(dynamic)”

#pragma omp parallel for shared(largest_factor, largest) schedule(dynamic)

然而,由于你只有10次迭代,我认为在这种情况下它不会有太大的不同。以下是我对您的代码所做的工作,以了解正在发生的事情:

#include <stdio.h>
#include <omp.h>

double fib(double n);

int main()
{
    int data[] = {124847,194747,194747,194747,194747,
                  194747,194747,194747,194747,194747,194747};
    int largest, largest_factor = 0;

    omp_set_num_threads(8);
    /* "omp parallel for" turns the for loop multithreaded by making each thread
     * iterating only a part of the loop variable, in this case i; variables declared
     * as "shared" will be implicitly locked on access
     */
    #pragma omp parallel for shared(largest_factor, largest)
    for (int i = 0; i < 10; i++) {
            int p, n = data[i];
        double time = omp_get_wtime();
        for (p = 3; p * p <= n && n % p; p += 2);
        printf("\n iteratnion %d, fib %f\n\n",i, fib(i+40));
        time = omp_get_wtime() - time;
        printf("time %f\n", time);

        if (p * p > n) p = n;
        #pragma omp critical
        {
           if (p > largest_factor) {        
              largest_factor = p;
              largest = n;      
              printf("thread %d: found larger: %d of %d\n", 
                    omp_get_thread_num(), p, n);
            } 
            else {
                printf("thread %d: not larger:   %d of %d\n", 
                        omp_get_thread_num(),     p, n);
            }
        }
    }

    printf("Largest factor: %d of %d\n", largest_factor, largest);
    return 0;
} 

double fib(double n) { 
if (n<=1) {
    return 1;
}
else {
    return fib(n-1)+fib(n-2);
}
}