2013-04-07 59 views
0

我有一个简单的程序,它生成(使用Boost)一些初始速度和位置,并计算传播一定距离所花费的时间。基于横向距离(x, y),将最终轴向(z)速度添加到矢量。下面是简单的程序:简单的程序在并行化后不工作

#include <iostream> 
#include <boost/random.hpp> 
#include <boost/random/normal_distribution.hpp> 

using namespace std; 




int main() 
{ 

    boost::mt19937 engine(static_cast<unsigned int>(time(0))); 


    boost::normal_distribution<double> nd(0.0, 1.0); 
    boost::variate_generator< boost::mt19937, boost::normal_distribution<double> > normal_std_one(engine, nd); 






    double coordX, coordY, coordZ, time; 
    double velX, velY, velZ; 

    const double factor = 0.01; 
    const double distance = 15.0; 

    vector<double> cont; 

    int i; 
    for(i=0; i<1000000000; i++) 
    { 
     coordX = factor*normal_std_one(); 
     coordY = factor*normal_std_one(); 
     coordZ = 0.0; 


     velX = normal_std_one(); 
     velY = normal_std_one(); 
     velZ = 20.0*normal_std_one()+300; 



     time = distance/velZ; 

     coordX += velX*time; 
     coordY += velY*time; 

     if(sqrt(coordX*coordX + coordY*coordY) < 0.02) 
     { 
      cont.push_back(velZ); 
     } 
    } 
    cout << cont.size() << endl; 


    return 0; 
} 

我想到了一个很好的补充将使用OpenMP并行化for -loop。这是我做的,加入循环开始之前以下行:

#pragma omp parallel for 

另外,我已经加入到-fopenmp编译器选项和`-fopenmp *的链接器设置。我的程序编译并没有错误链接,但是当我执行这个文件我得到的消息:

Process terminated with status -1073741819 (0 minutes, 2 seconds) 

我做了什么错在这里是我不清楚。我使用Windows和g ++(通过Code :: Blocks IDE)。

+0

您有多个线程正在同时尝试更新“cont”状态... – 2013-04-07 10:52:15

+0

@OliCharlesworth因此,如果使用向量,那么使用OpenMP是不可能的? – BillyJean 2013-04-07 10:54:05

+0

如果将它替换为cont.push_back [i] = velZ,它会有什么区别吗? ? – SChepurin 2013-04-07 11:17:18

回答

1

我张贴这个答案,但不是评论只是为了积累结果,并避免长长的评论列表。它适用于来自Microsoft PPL的parallel_for,如果您正确处理std:vector的大小以避免out-of-range异常。但问题是,当i超过~20000时,boost::variate_generator无法处理多个请求,并在程序崩溃时产生APPLICATION_FAULT_INVALID_POINTER_READ错误。

更新:当不使用boost::variate_generator(简单地将值分配给矢量的索引)上的双核笔记本它运行没有错误,但示出了相反到预期的结果 - 顺序代码运行速度比与多线程parallel_for

0

您不能在多个线程间使用不同步的cont.push_back。它不是线程安全的。您需要使用不同的容器,或者在访问时使用某种互斥锁。如果重要的话,您可能还需要做一些事情来维护它们进入容器的顺序。

+0

订单没有任何关系。你的建议是什么?我是OpenMP的初学者。 – BillyJean 2013-04-07 10:58:47

+0

我试图通过添加'#pragma omp critical'来使其成为关键部分,但现在我得到消息'“内存不能在执行时被读取 – BillyJean 2013-04-07 11:27:32