简体   繁体   English

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

[英]threading in c++, finding largest entry in 2d array

I'm having some trouble finding the largest entry in a 2d array with a threaded function. 我在查找具有线程函数的2d数组中的最大条目时遇到了一些麻烦。 I've been glued to the screen for hours now, and I could use some help. 我已经被粘在屏幕上了几个小时,我可以使用一些帮助。

Here is the code: 这是代码:

#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";
}

I believe I'm setting everything up correctly, but I've just learned how to use async so I'm sure something is incorrect. 我相信我已经正确设置了所有内容,但是我刚刚学习了如何使用异步功能,因此可以肯定有些错误。 When run, I get zero as the output of the largest entry, which is wrong, and I get a runtime much longer than I'm expecting. 运行时,我得到的最大条目的输出为零,这是错误的,并且我得到的运行时间比我期望的要长得多。

Here is the output: 这是输出:

 The largest entry is 0
runtime : 13.8261

I think I'm passing in largestEntry to the threaded function incorrectly, but I have no idea how to fix it. 我想我没有正确地将largestEntry传递给线程函数,但是我不知道如何解决它。 The threaded function, getLargest , is supposed to find the largest entry of the array it's provided, and when I create the threads I assign each of them a portion of the array. 线程函数getLargest应该找到它提供的数组的最大条目,并且当我创建线程时,我将每个线程分配给数组的一部分。

Any advice anyone could provide would be much appreciated. 任何人都可以提供的任何建议将不胜感激。

Currently you are just changing the value of the local largestEntry parameter. 当前,您只是在更改本地largestEntry参数的值。 This will not change anything in the calling program. 这不会更改调用程序中的任何内容。

One solution is to pass in largestEntry as a reference (change your function to say double &largestEntry in its parameter list) 一种解决方案是传入largestEntry作为参考(将函数更改为在其参数列表中说double &largestEntry

Note that this has nothing to do with threading, you could just call your function normally to test it. 请注意,这与线程无关,您可以正常调用函数进行测试。

Edit: I had trouble with using a reference when I tried it (could just be a old compiler) - if references don't work, you could always pass the largestEntry as a pointer - double *largestEntry in the function parameter list and a few * and & placed in the rest of the code. 编辑:我在尝试使用引用时遇到了麻烦(可能只是一个旧的编译器)-如果引用不起作用,则始终可以将largestEntry作为指针传递-函数参数列表中的double *largestEntry和一些*&放在其余的代码中。

The problem has been described in the last answer by The Dark. The Dark已在最后一个答案中描述了该问题。 However, i find the solution not ideal. 但是,我发现解决方案并不理想。 For me, it would be more logical that your function returned the value thus found rather than write it in a parameter. 对我来说,逻辑上说,您的函数返回这样找到的值,而不是将其写入参数中,这将更加合乎逻辑。

That way you can use the get() function of the future to obtain the answer when the threads are finished, and you do not use references or pointers where it is really not needed. 这样,您可以使用future的get()函数在线程完成时获得答案,并且在真正不需要它的地方不使用引用或指针。

Note: simply using a reference would not work here because the parameter to std::async are copied, the same way as for std::thread . 注意:在这里仅使用引用将不起作用,因为复制了std::async的参数,与std::thread方式相同。 If you want it to work with a reference, you need to use std::ref ( link ) in that case. 如果希望它与参考一起使用,则在这种情况下,需要使用std::reflink )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM