Я запустил программу OpenMP для выполнения метода Якоби, и он работал очень хорошо, 2 потока выполнялись чуть более 2х1 потока и 4 потока в 2 раза быстрее, чем 1 поток. Я чувствовал, что все работает отлично ... пока я не достиг ровно 20, 22 и 24 потоков. Я все разбив его, пока я не имел эту простой программуЯркое замедление OpenMP для определенного номера потока
#include <stdio.h>
#include <omp.h>
int main(int argc, char *argv[]) {
int i, n, maxiter, threads, nsquared, execs = 0;
double begin, end;
if (argc != 4) {
printf("4 args\n");
return 1;
}
n = atoi(argv[1]);
threads = atoi(argv[2]);
maxiter = atoi(argv[3]);
omp_set_num_threads(threads);
nsquared = n * n;
begin = omp_get_wtime();
while (execs < maxiter) {
#pragma omp parallel for
for (i = 0; i < nsquared; i++) {
//do nothing
}
execs++;
}
end = omp_get_wtime();
printf("%f seconds\n", end - begin);
return 0;
}
А вот некоторые выходы для различных чисел резьбы:
./a.out 500 1 1000
0.6765799 seconds
./a.out 500 8 1000
0.0851808 seconds
./a.out 500 20 1000
19.5467 seconds
./a.out 500 22 1000
21.2296 seconds
./a.out 500 24 1000
20.1268 seconds
./a.out 500 26 1000
0.1363 seconds
Я понял бы большой спад, если он по-прежнему для всех потоков после 20, потому что я бы понял, что это будет поток накладных расходов (хотя я чувствовал, что это немного экстремально). Но даже изменение n оставляет времена 20, 22 и 24, чтобы оставаться неизменным. Изменение maxter до 100 уменьшает его до примерно 1,9 секунды, 2,2 секунды, ..., что означает, что только создание потока вызывает замедление, а не внутреннюю итерацию.
Это как-то связано с ОС, пытающейся создать потоки, которых у нее нет? Если это что-то значит, omp_get_num_procs()
возвращает 24, и это на процессорах Intel Xeon (поэтому 24 включает в себя гиперпотоки?)
Спасибо за помощь.
Какой компилятор и опции вы используете? У вас есть оптимизация (например, -O3 с GCC или/O2 с MSVC)? Я не думаю, что это интересно, если оптимизация не используется. –
@Zboson Я использовал GCC изначально без оптимизации (вычисление оптимизации портит мою урезанную версию), но теперь, когда я дал GCC-O3, проблема все еще возникает. Теперь я еще более смущен. –
Все ли какие-либо задачи, выполняемые в системе все время? Ваша система имеет 12 физических ядер (и 24 логических ядра). Любая задача, которая составляет 100%, может сильно повлиять на два потока, а все остальные потоки должны ждать медленного завершения. –