У OpenMP есть накладные расходы, которые добавляют постоянный термин к расчету времени. Позвольте мне привести пример.
Предположим, что ваш алгоритм завершен в A*n
, где A - некоторая константа, а n - количество элементов, которые вы будете перебирать. Предположим также, что ваш алгоритм идеально распараллеливается, так что если у вас есть k
потоков, то распараллеливаемый алгоритм заканчивается в O(n)/k
времени. Из-за накладных расходов OpenMP время запуска будет A*n/k + B
, где B - накладные расходы. Поэтому для того, чтобы вы могли видеть любую выгоду от OpenMP A*n/k + B < A*n
. Для некоторого диапазона значений n [0, threshhold] OpenMP будет фактически медленнее, чем серийный алгоритм из-за накладных расходов B
.
Еще один важный момент заключается в том, что OpenMP имеет разные служебные/пороговые значения в зависимости от того, был ли он уже использован в коде. Я называю это холодными и теплыми порогами.
dtime_cold = omp_get_wtime();
foo(); //cold - OpenMP has not been called before
dtime_cold = omp_get_wtime() - dtime_cold;
dtime_warm = omp_get_wtime();
foo(); //warm - OpenMP has already been called once
dtime_warm = omp_get_wtime() - dtime_warm;
Если n
достаточно велико, то постоянные термины insignficant в этом случае пороги не имеют значения.
Кратко глядя на ваш код, я бы предложил попробовать большее значение V (у вас установлено 1000). У OpenMP есть накладные расходы, поэтому вы не увидите его benfit до некоторого порога –
@Zboson спасибо, это работает! – Betelgeuse