我很难用c ++编写一个比我的非线程版本更准确,更快的线程程序。
我找到了随机双打的2d数组中的最大条目。
以下是一般代码:
void getLargest(double** anArray, double largestEntry, int dimLower, int dimUpper, int dim) {
for (int i = dimLower; i < dimUpper; i++) {
for (int j = 0; j < dim; j++) {
if (anArray[i][j] > largestEntry) {
largestEntry = anArray[i][j];
}
}
}
}
int main(){
// Seed the random number generator
srand( time(NULL));
// 2D array dimension
int dim = 30000;
// Specify max values
double max = (double) (dim * dim * dim);
double min = (double) (dim * dim * dim * -1.0);
double t1 = get_wallTime();
// Create a 2D array
double **myArray = new double*[dim];
for (int i=0; i<dim; i++){
myArray[i] = new double[dim];
for (int j=0; j<dim; j++){
// generate random number
myArray[i][j] = genRandNum(min, max);
}
}
double largestEntry = 0.0;
int portion = dim / 5;
std::future<void> thread1 = std::async (std::launch::async, getLargest, myArray, largestEntry, 0, portion, dim);
thread1.get();
std::future<void> thread2 = std::async (std::launch::async, getLargest, myArray, largestEntry, portion, (portion * 2), dim);
thread2.get();
std::future<void> thread3 = std::async (std::launch::async, getLargest, myArray, largestEntry, (portion * 2), (portion * 3), dim);
thread3.get();
std::future<void> thread4 = std::async (std::launch::async, getLargest, myArray, largestEntry, (portion * 3), (portion * 4), dim);
thread4.get();
std::future<void> thread5 = std::async (std::launch::async, getLargest, myArray, largestEntry, (portion *4), dim, dim);
thread5.get();
double t2 = get_wallTime();
double t3 = t2 - t1;
cout << " The largest entry is " << largestEntry << endl;
cout << "runtime : " << t3 << "\n";
}
我有适当的#includes。
我理解我的代码是从每个线程更新双largestEntry
,如果线程正在处理的2d数组的部分具有比它之前的线程更大的条目。然后我输出最大的条目和运行时。
这是输出:
The largest entry is 0
runtime : 14.7113
这比我预期的要快,并且最大的条目不应该为零。基本上,我很难找到原因。我使用async
时感觉不太舒服,但是在我之前使用此方法时效果非常好。我知道我没有正确更新largestEntry
,但我不确定我在哪里犯了错误。
感谢你们给予的任何建议。
答案 0 :(得分:0)
您按值largestEntry
将getLargest
传递给main
,因此更新时只会更新函数中的值,而不会更新thread1.get()
中的值。
另外两个注意事项:largestEntry
等调用应该都在创建线程之后,所以它们都会同时运行。
两个,每个线程应该返回它自己的{{1}}值(它可以是未来的值),然后比较那些找到最大值。如果它们都引用相同的变量,那么你将进入线程之间的竞争条件,CPU缓存抖动,以及可能的错误答案,具体取决于优化器如何处理对hugeEntry的更新(它可以避免写入值,直到所有循环已经完成了。