【发布时间】:2014-05-19 06:33:50
【问题描述】:
我正在编写一个程序,其中一堆不同的类都存储在一个向量中,使用公共数据结构对私有成员执行并行操作。我想使用 OpenMP 为多个处理器并行化它,但我对代码中的两个操作有两个问题,这两个操作都在下面的示例中用 cmets 表示,显示了程序逻辑的简化形式。
#include <omp.h>
#include <iostream>
#include <sys/timeb.h>
#include <vector>
class A {
private :
long _i;
public :
void add_i(long &i) { _i += i; }
long get_i() const { return _i; }
};
int main()
{
timeb then;
ftime(&then);
unsigned int BIG = 1000000;
int N = 4;
std::vector<long> foo(BIG, 1);
std::vector<A *> bar;
for (unsigned int i = 0; i < N; i++)
{
bar.push_back(new A());
}
#pragma omp parallel num_threads(4)
{
for(long i = 0; i < BIG; i++)
{
int thread_n = omp_get_thread_num();
// read a global variable
long *to_add = &foo[i];
// write to a private variable
bar[thread_n]->add_i(*to_add);
}
}
timeb now;
ftime(&now);
for (int i = 0; i < N; i++)
{
std::cout << bar[i]->get_i() << std::endl;
}
std::cout << now.millitm - then.millitm << std::endl;
}
第一个注释解决了从全局 foo 读取的问题。这是“虚假共享”(或数据晃动)吗?我阅读的大多数资源都在写操作方面谈论虚假共享,但我不知道这是否适用于读操作。
第二条注释解决了对 bar 中类的写入操作。同样的问题:这是虚假分享吗?它们写入相同全局数据结构中的元素(根据我的阅读,晃动),但只作用于元素内的私有数据。
当我用 for 循环替换 OpenMP 宏时,程序速度提高了大约 25%,所以我猜我做错了什么......
【问题讨论】:
-
你的例子很奇怪。你说的是一堆不同的类,但我认为你的意思是同一个类的一堆不同的对象?你说的一堆是指四个。那不是很多。但它也被设置为似乎任意的线程数。您为什么不向我们展示您的非并行代码,然后我们可以向您展示如何最好地并行化它。