我必须用SDE解决热量方程。 程序运行正常,但速度很慢。
简而言之:我编写了一个程序,可以在矢量上随机设置许多粒子并将它们移动一段时间。
在时间t之后,计算每个网格箱中的所有粒子并将该数字保存在计数向量中。现在我必须做runs
= 1000才能获得好结果。 (这些函数属于一个类)。
void makeruns(const int runs){
for(int i=0; i<runs; ++i){
setandmove();
}
}
void setandmove(){
for(int t=0; t<timesteps; ++t){
//set new particles and move particles on the grid
}
//Endposition is saved in the list Y_omega
//count number of points in bins
for(auto it=Y_omega.begin(); it!=Y_omega.end(); ++it){
double valf = it->first;
double vals = it->second;
auto it_f = std::lower_bound(intervall.begin(),intervall.end(),valf, [](auto P, auto V) -> bool {return P< V;});
auto it_s = std::lower_bound(intervall.begin(),intervall.end(),vals, [](auto P, auto V) -> bool {return P < V;});
int dist1 = std::distance(intervall.begin(),it_f);
int dist2 = std::distance(intervall.begin(),it_s);
count.at(dist1 + s*dist2)=count.at(dist1 + s*dist2) + 1;
}
Y_omega.clear();
}
是否有可能制作线程,至少对于第一部分,或者当他们在向量count
std::thread t1(makeruns, 250);
std::thread t2(makeruns, 250);
std::thread t3(makeruns, 250);
std::thread t4(makeruns, 250);
t4.join();
t3.join();
t2.join();
t1.join();
可悲的是,我并不精通线程。
答案 0 :(得分:3)
如果多个线程要读取和写入相同的数据位置,则代码必须同步这些访问。否则行为未定义。
正如Martin Bonner在一篇文章中提到的,一种方法是让每个线程分别保留自己的统计信息,并在最后组合各种线程结果。
另一种方法是使用原子变量。如果count
数组包含std::atomic<int>
而不是普通int
(或者您的计数数据类型实际上是什么),那么编写的代码(只需更改一次)就可以正常工作:replace < / p>
count.at(dist1 + s*dist2)=count.at(dist1 + s*dist2) + 1;
与
++count.at(dist1 + s*dist2);
或
++count[dist1 + s*dist2];
选择采用哪种方法取决于正在处理的数据的性质。
答案 1 :(得分:1)
如果您在每次计算后使用向量插入结果,那么您需要确保一次只有一个线程对向量执行插入操作。由于插入操作不是很复杂,插入时阻塞其他线程不会有时间损失。
最好的方法是使用互斥对象;
std::mutex m; // may be a global object or may be shared by a using a pointer.
Vector counting_vector; //some vector object for keeping result of each computation.
void threadWorker(int count){
//here
//create vector that will be used for set and move operation. Each thread will have it's own vector.
while(count-->0){
//perform the set and move operation on the vector;
result=;/*the computed result*/
m.lock();
//code between lock() and unlock() won't run concurrently.
counting_vector.insert(result);//insert or push_back into the vector
m.unlock();
}
}