2012-04-01 85 views
1

在我之前的问题中 Shared vectors in OpenMP 有人说可以让不同的线程在共享向量上读写,只要不同线程访问向量的不同元素。 如果不同的线程必须读取矢量的所有(有时是相同的)元素,如下例所示?OpenMP中的共享向量2

#include <vector> 

int main(){ 

vector<double> numbers; 
vector<double> results(10); 
double x; 

//write 25 values in vector numbers 
for (int i =0; i<25; i++){ 
    numbers.push_back(cos(i)); 
} 

#pragma omp parallel for default(none) \ 
shared(numbers, results) \ 
private(x) 
    for (int j = 0; j < 10; j++){ 
     for(int k = 0; k < 25; k++){ 
      x += 2 * numbers[j] * numbers[k] + 5 * numbers[j * k/25]; 
     } 
     results[j] = x;  
    } 

    return 0; 

} 

将这个并行是缓慢的,因为只有一次一个线程可以读取向量的任何元素,或者这是不是这样的?我能否通过条款firstprivate(numbers)解决问题?

会是有意义的创建载体的阵列,使得每个线程都有自己的载体?

例如:

vector<double> numbersx[**-number of threads-**]; 

回答

2

阅读元素来自多个线程的向量不是问题。代码中没有同步,所以它们将被同时访问。

这样,您正在使用矢量的大小,你不会有任何缓存出现了问题或者,虽然更大的载体,你可能会由于高速缓存访​​问模式有些缓慢起伏。在这种情况下,数字数据的单独副本可以提高性能。

+0

感谢您的回复。实际上,我实际上想要使用的矢量可能有多达67 * 10^6个条目(使用double或float数据类型)。那么我应该如何制作副本? “你的代码没有同步”是什么意思? – user1304680 2012-04-01 22:05:23

+0

@ user1304680,这听起来像你是多方面的新手,所以我建议你阅读更多的背景信息。简而言之,同步是一种限制对资源的访问的方式,以便多个线程可以读取并修改它。这是确保逻辑正确性的一种方法,但它会杀死并行性。同步是通过原子操作,关键部分,互斥体完成的。 – 2012-04-01 22:10:30

+0

@ user1304680,我建议不要做一个副本开始和验证性能缩放。如果性能不与内核数量成比例,那么您可以考虑优化缓存访问。 – 2012-04-01 22:14:51

1

更好的方法:

#include <vector> 

int main(){ 

vector<double> numbers; 
vector<double> results(10); 

//write 25 values in vector numbers 
for (int i =0; i<25; i++){ 
    numbers.push_back(cos(i)); 
} 

#pragma omp parallel for 
    for (int j = 0; j < 10; j++){ 
     double x = 0; // make x local var 
     for(int k = 0; k < 25; k++){ 
      x += 2 * numbers[j] * numbers[k] + 5 * numbers[j * k/25]; 
     } 
     results[j] = x; // no race here  
    } 

    return 0; 

} 

这将是缓慢的还挺由于事实,那就是没有太多的工作共享同一的

+0

谢谢。我可以看到你是如何在循环中声明x的,这已经在http://stackoverflow.com/questions/9953905/shared-vectors-in-openmp中讨论过了,但是它自从向量'结果'和'数字'是隐含共享的,对吗?可能没有太多的工作要分享,但我的问题是,如果一般情况下并行化会很慢,因为不同的线程读取矢量“数字”的相同元素。 – user1304680 2012-04-01 19:19:11

+0

阅读不太可能是一个性能问题,写作可能是由于虚假分享(谷歌)。你可以通过分割外部循环来解决它。 – Anycorn 2012-04-01 19:24:23