2015-11-05 2 views
0

Я изо всех сил пытаюсь написать поточную программу на C++, которая является точной и быстрой, чем моя не-потоковая версия.найти наибольшую запись в массиве 2d с помощью потоковой функции

Я нахожу самую большую запись в 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

Вы передаете largestEntry в getLargest по значению, поэтому при его обновлении обновляется только значение внутри функции, а не значение в main.

Два других примечания: thread1.get() и т. Д. Вызовы должны быть все после создания потоков, поэтому все они запускаются одновременно.

Два, каждый поток должен вернуть свое значение для largestEntry (это может быть значение будущего), а затем сравнить их, чтобы найти самый большой. Если все они ссылаются на одну и ту же переменную, вы столкнетесь с условиями гонки между потоками, провалом кэша процессора и, возможно, плохими ответами, в зависимости от того, как оптимизатор обрабатывает обновления до наибольшегоEntry (он мог бы избежать записи значения до тех пор, пока все петли было сделано).

+0

Спасибо за ваш комментарий. Каким будет решение для передачи 'largeEntry' по ссылке вместо значения? Я пробовал несколько вещей, но я не уверен, как это работает на C++. – slippeel

+0

@slippeel Вы можете передать его ссылкой или указателем, но каждый поток должен будет работать со своей собственной копией 'mostEntry'. Возвращение его в результате 'getLargest' (которое станет значением будущего) было бы лучше, чем передача, это как параметр. – 1201ProgramAlarm

Смежные вопросы