我努力在C++中编写一个线程化程序,该程序比我的非线程化版本准确且快速。查找带有线程函数的二维数组中的最大条目
我在二维随机双数组中找到最大的条目。
这里是通用代码:
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。 我理解我的代码,因为如果线程正在处理的2d数组的部分比它之前的线程有更大的条目,那么我将更新每个线程的双重largestEntry
。然后输出最大的条目和运行时。
这里是输出:
The largest entry is 0
runtime : 14.7113
这种方式运行速度比我期待它来,和最大的记录不应该是零。基本上,我很难找到原因。我不太喜欢使用async
,但是当我以前,这种方法工作得很好。我知道我没有正确更新largestEntry
,但我不确定我犯了什么错误。
感谢您的任何建议,你们可以给。
感谢您的评论。通过引用传递'largestEntry',而不是值的解决方案是什么?我已经尝试了一些东西,但我不确定它在C++中的工作原理。 – slippeel
@slippeel你可以通过引用或指针传入它,但每个线程都需要使用它自己的'largestEntry'副本。作为'getLargest'(将成为未来的价值)的结果返回它会比传递它作为一个参数更好。 – 1201ProgramAlarm