在c ++中进行线程化,在2d数组中找到最大的条目

时间:2015-11-06 04:02:42

标签: c++ arrays multithreading

我在使用线程函数找到2d数组中的最大条目时遇到了一些麻烦。我已经被粘在屏幕上几个小时了,我可以帮忙。

以下是代码:

#include <iostream>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <random>
#include <ctime>
#include <future>
#include <thread>

using namespace std;

// A vanilla random number generator
double genRandNum(double min, double max){

  return min + (rand() / (RAND_MAX / (max - min)));

}

double get_wallTime() {
    struct timeval tp;
    gettimeofday(&tp, NULL);
    return (double) (tp.tv_sec + tp.tv_usec/1000000.0);
} 

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]; 
            }
        }
    }

}

// Main routine
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;
  double largestEntry2 = 0.0;
  double largestEntry3 = 0.0;
  double largestEntry4 = 0.0;
  double largestEntry5 = 0.0;
  int portion = dim / 5;
  std::future<void> thread1 = std::async (std::launch::async, getLargest, myArray, largestEntry, 0, portion, dim);

  std::future<void> thread2 = std::async (std::launch::async, getLargest, myArray, largestEntry2, portion, (portion * 2), dim);

  std::future<void> thread3 = std::async (std::launch::async, getLargest, myArray, largestEntry3, (portion * 2), (portion * 3), dim);

  std::future<void> thread4 = std::async (std::launch::async, getLargest, myArray, largestEntry4, (portion * 3), (portion * 4), dim);

  std::future<void> thread5 = std::async (std::launch::async, getLargest, myArray, largestEntry5, (portion *4), dim, dim);
  thread1.get();
  thread2.get();
  thread3.get();
  thread4.get();

  thread5.get();


  if (largestEntry2 > largestEntry) {
     largestEntry = largestEntry2;
  } 
  if (largestEntry3 > largestEntry) {
    largestEntry = largestEntry3;
  }
  if (largestEntry4 > largestEntry) {
    largestEntry = largestEntry4;
  }
  if (largestEntry5 > largestEntry) {
    largestEntry = largestEntry5;
  }

  double t2 = get_wallTime();
  double t3 = t2 - t1;

  cout << " The largest entry is " << largestEntry << endl;  

  cout << "runtime : " <<  t3 << "\n";
}

我相信我正确地设置了所有内容,但我刚学会了如何使用异步,所以我确定某些内容不正确。在运行时,我得到零作为最大条目的输出,这是错误的,并且我得到的运行时间比我预期的要长。

这是输出:

 The largest entry is 0
runtime : 13.8261

我认为我错误地将largestEntry传递给了线程函数,但我不知道如何修复它。线程函数getLargest应该找到它提供的数组的最大条目,当我创建线程时,我为它们分配一部分数组。

任何人都可以提供的建议将非常感激。

2 个答案:

答案 0 :(得分:2)

目前,您只是更改了本地largestEntry参数的值。这不会改变调用程序中的任何内容。

一种解决方案是传递largestEntry作为参考(将您的函数更改为在其参数列表中说double &largestEntry

请注意,这与线程无关,您可以正常调用函数来测试它。

编辑:我在尝试使用引用时遇到了麻烦(可能只是一个旧的编译器) - 如果引用不起作用,你总是可以将largestEntry作为指针传递 - {{1} }在函数参数列表中,并在代码的其余部分放置了一些double *largestEntry*

答案 1 :(得分:2)

问题已在The Dark的最后一个答案中描述。但是,我发现解决方案并不理想。对我来说,你的函数返回如此找到的值而不是将它写入参数更合乎逻辑。

这样你可以使用future的get()函数在线程完成时获得答案,并且不使用真正不需要的引用或指针。

注意:仅使用引用在此处不起作用,因为std::async的参数被复制,与std::thread的方法相同。如果您希望它与参考一起使用,则需要在这种情况下使用std::reflink)。