C++ 使用OpenMP的并发性和优化
我正在学习OpenMP。为了做到这一点,我试图使现有的代码并行。但我似乎在使用OpenMP的时候比不使用OpenMP的时候更糟糕 我的内环:C++ 使用OpenMP的并发性和优化,c++,openmp,C++,Openmp,我正在学习OpenMP。为了做到这一点,我试图使现有的代码并行。但我似乎在使用OpenMP的时候比不使用OpenMP的时候更糟糕 我的内环: #pragma omp parallel for for(unsigned long j = 0; j < c_numberOfElements; ++j) { //int th_id = omp_get_thread_num(); //printf("thread %d, j = %d\n",
#pragma omp parallel for
for(unsigned long j = 0; j < c_numberOfElements; ++j)
{
//int th_id = omp_get_thread_num();
//printf("thread %d, j = %d\n", th_id, (int)j);
Point3D current;
#pragma omp critical
{
current = _points[j];
}
Point3D next = getNext(current);
if (!hasConstraint(next))
{
continue;
}
#pragma omp critical
{
_points[j] = next;
}
}
#pragma omp parallel for
for(无符号长j=0;j
_点是点映射,定义为:
typedef boost::unordered_map<unsigned long, Point3D> pointMap_t;
typedef boost::无序的点映射;
没有OpenMP,我的运行时间是44.904s。启用OpenMP后,在具有两个内核的计算机上,它是64.224s。我做错了什么?为什么要将读写内容包装到关键部分的
\u points[j]
?我不是一个C++程序员,但我并不认为你需要这些部分。正如您所写的(命名为关键部分),每个线程都将等待,而另一个线程将通过每个部分。这很容易使程序变慢。使用OpenMP时,关键部分的查找和写入点可能会降低性能。单线程,这不会导致任何争用
在并行编程环境中,像这样共享种子数据似乎适得其反。您可以重新构造以避免这些争用点吗?您需要显示代码的其余部分。从一个评论到另一个答案,你似乎在使用地图。这真是个坏主意,尤其是当您将0..n个数字映射到值时:为什么不使用数组
如果您真的需要使用容器,请考虑使用
中的那些,我同意最好看到一些工作代码。 这里的最终问题是,在一个平行区域内存在临界点,临界点(a)本身和自身都非常昂贵,(b)根据定义,扼杀了并行性。分配给当前certainl的任务不需要在临界值内,因为它是私有的;我也没想到这个_points[j]的任务会是什么,但我不知道地图是做什么的,所以就这样吧
但是您有一个循环,其中有大量开销,线程数(两个关键区域)呈线性增长,以完成少量实际工作(看起来像是沿着链表走)。这永远都不会是一笔好交易……没有它就不会有问题。我不认为我可以同时从两个不同的线程更改映射。还有其他方法吗?我不习惯并行编程。@Vitor-我看不出如果只删除关键部分,为什么会出现故障。代码中有些我们看不到的东西也许<代码>\循环执行时,没有向点添加或删除点,对吗?函数调用在当前条目之外是否有副作用?例外情况在哪里?即使删除了关键部分,也可能导致严重的减速。例如,请参见gdb的@Steve Townsend:[新线程0x7ffff0ccd710(LWP 13329)]***检测到glibc***/home/vitorpy/openmp/test:double-free或corruption(fasttop):0x00000000027f8be0***。bt显示它发生在无序的_映射操作符[]上。函数调用没有副作用。@olicharlesworth我来看看。谢谢,你说得对。地图大部分是旧设计的遗留物,在旧设计中,ID并不总是按顺序排列的。我把它做成了一个数组。它仍然很慢,但我想我可能遇到了错误的共享问题或其他问题。@Vitto Py:请尝试创建一个小的可编译代码示例来说明这个问题。您将代码简化得如此之多,以致于将问题抽象出来。要尝试的一件事是将“hasControint”作为静态内联,以避免支付函数调用的代价。