Вот некоторые замечания по вашему коду.
Использование огромного количества потоков не принесет вам никакой выгоды и является вероятной причиной ваших проблем. Создание потока требует затрат времени и ресурсов. Из-за временных затрат это, вероятно, будет основным временем в вашей программе, и ваша параллельная программа будет намного длиннее, чем ее последовательная версия. Что касается стоимости ресурсов, каждый поток имеет свой собственный сегмент стека. Его размер зависит от системы, но типичные значения измеряются в МБ. Я не знаю характеристик вашей системы, но с 100000 потоков это, вероятно, причина сбоя вашего кода. У меня нет объяснения для сообщения о cygwin.s, но после переполнения стека поведение может быть странным.
Потоки - это средство, позволяющее упорядочить код, и для параллелизма данных большую часть времени бесполезно иметь больше потоков, чем количество логических процессоров в вашей системе. Пусть openmp установит его, но вы можете поэкспериментировать позже, чтобы настроить это число.
Кроме того, есть и другие проблемы.
rand()
не является поточно-безопасным , поскольку использует глобальное состояние, которое будет изменяться одновременно потоками. rand_r()
, поскольку состояние генератора случайных чисел не является глобальным и может храниться в каждом потоке.
Не следует изменять общую переменную, например result
, без атомарного доступа , поскольку одновременный доступ к потокам может привести к неожиданным результатам. Хотя использование атомной модификации для каждого значения безопасно, это не очень эффективное решение. Атомный доступ очень дорог, и лучше использовать сокращение, которое делает локальное накопление в каждом потоке, и уникальный атомарный доступ в конце.
#include <omp.h>
#include <iostream>
#include <random>
#include <time.h>
int main()
{
int runs = 100000;
double result = 0.0;
#pragma omp parallel
{
// per thread initialisation of rand_r seed.
unsigned int rand_state=omp_get_thread_num()*time(NULL);
// or whatever thread dependent seed
#pragma omp for reduction(+:result)
for(int i=0; i<runs; i++)
{
double d = double(rand_r(&rand_state))/double(RAND_MAX);
result += d;
}
}
result /= double(runs);
std::cout << "The computed average over " << runs << " runs was "
<< result << std::endl;
return 0;
}