2015-11-05 34 views
0

我努力在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,但我不确定我犯了什么错误。

感谢您的任何建议,你们可以给。

回答

0

您按值将largestEntry转换为getLargest,因此更新时只更新函数内的值,而不更新main中的值。

其他两个注意事项:thread1.get()等调用应该都是在创建线程之后,因此它们全部同时运行。

二,每个线程应该返回它自己的值largestEntry(它可以是未来的价值),然后比较那些找到最大值。如果它们都引用相同的变量,那么你将进入线程之间的竞争状态,CPU缓存抖动和可能的错误答案,这取决于优化器如何处理对largestEntry的更新(它可以避免将值写出直到所有循环已完成)。

+0

感谢您的评论。通过引用传递'largestEntry',而不是值的解决方案是什么?我已经尝试了一些东西,但我不确定它在C++中的工作原理。 – slippeel

+0

@slippeel你可以通过引用或指针传入它,但每个线程都需要使用它自己的'largestEntry'副本。作为'getLargest'(将成为未来的价值)的结果返回它会比传递它作为一个参数更好。 – 1201ProgramAlarm