2013-04-11 24 views
0

我有一段代码是我前一段时间编写的。它的唯一目的是用openMP做实验。但我最近将MacBook Pro Lion(2011年初)改装为MacBook Pro Mountain Lion(2013年初)。如果它有助于获得更多其他信息的硬件,我会很乐意给予他们。 代码在旧版本上运行良好,这意味着8个线程在我的处理器上获得了100%(98%min)的负载。现在,在我的新机器上重新编译的相同代码只能获得62%的最大处理器负载。即使我提出了线程。处理器负载均采用“istat pro”进行测量。使用不同版本的操作系统的OpenMP性能差异

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

编辑:问题似乎解决,如果我删除在#pragma omp parallel for shared(largest_factor, largest)。所以我得到#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); 
} 
} 

回答

0

看不到正在使用的所有线程的主要原因是,每个线程需要不同的时间(由于递归函数或内循环),你只需要10次​​迭代。快速线程完成得很快,然后只剩下几个线程运行。当你第一次运行你的代码时,它会从100%开始,并且随着快速线程完成和最后几个慢速线程仍在运行而下降。如果将迭代次数更改为100(并增加数据数组),您将会看到CPU使用率达到100%的时间更长。我在代码中添加了一些定时打印输出。

另外我认为你有一个与你的共享变量的竞争条件,所以我把一个关键部分。

要回答你关于没有“for”语句的代码的问题那是在8个不同的线程上运行相同的代码!而不是线程运行一个特定的迭代,他们每个运行所有10次迭代。这将不会比运行单个线程更快,甚至更慢。

最后,因为每次迭代需要不同的时间,一般你应该使用“schedual(动态)”像这样

#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); 
} 
} 
+0

对'largest_factor'赋值和测试p'值是否更大时仍存在数据争用条件。 – 2013-04-12 14:49:42

+0

我想我明白你的意思了。好的,我解决了这个问题。嘿,这是一个低洼的水果问题! – 2013-04-12 16:54:29

+0

我刚刚查看了一个经过测试的代码,但空闲时间现在为50到63%。但是你说它可能会变慢。我会试着了解你对代码做了什么。感谢您的帮助。 – 2013-04-15 17:36:46

相关问题