我有这样一段代码:
int n=5;
Eigen::VectorXd vec(n);
vec.setZero();
for(int i=0;i<100;i++)
{
int idx = i%n;
vec(idx)+=(i/n);
}
std::cout<<vec<<endl;
我想把它并行化。
我想出了一个避免数据依赖的方法。
int n=5;
int num_thread = 6;
omp_set_num_threads(num_thread);
Eigen::MatrixXd mat(num_thread,n);
mat.setZero();
#pragma omp parallel for
for(int i=0;i<100;i++)
{
int idx_pool = omp_get_thread_num();
int idx_col = i%n;
mat(idx_pool,idx_col)+=(i/n);
}
Eigen::VectorXd vec(n);
vec = mat.rowwise().sum();
std::cout<<vec<<endl;
我在想,这是不是一种方法?
2条答案
按热度按时间jgovgodb1#
假设您的真实的代码在并行循环中具有更高的工作负载,那么这是一种非常有效的方法(如果工作负载较低,并行化本身可能就没有意义)。最先进的方法是使用约简(如@VictorEijkhout所述),但如果您必须定义一个自定义变量,则会很麻烦(并且根据情况没有明显的性能改善)。除了在一些特定的情况下,我不认为内存问题是真实的的问题:当使用归约时,无论如何,线程具有被归约的变量/数组的隐藏私有副本。
fcy6dtqo2#
您已经解决了争用条件问题,但却成倍增加了程序的内存需求。您还引入了一个非并行操作:
rowwise().sum()
,这会降低性能增益。因为你在做一种归约,你可以使用OpenMP的
reduction
子句,如果+
运算符被重载了,对于VectorXd
类,是吗?否则你可以自己定义。