Я работаю с OpenMP, чтобы получить алгоритм с почти линейным ускорением. К сожалению, я заметил, что не могу получить желаемое ускорение.Нет ускорения с OpenMP
Итак, чтобы понять ошибку в моем коде, я написал другой код, простой, просто чтобы проверить, что ускорение было в принципе доступно на моем оборудовании.
Это игрушка пример я писал:
#include <omp.h>
#include <cmath>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <iostream>
#include <stdexcept>
#include <algorithm>
#include "mkl.h"
int main() {
int number_of_threads = 1;
int n = 600;
int m = 50;
int N = n/number_of_threads;
int time_limit = 600;
double total_clock = omp_get_wtime();
int time_flag = 0;
#pragma omp parallel num_threads(number_of_threads)
{
int thread_id = omp_get_thread_num();
int iteration_number_local = 0;
double *C = new double[n]; std::fill(C, C+n, 3.0);
double *D = new double[n]; std::fill(D, D+n, 3.0);
double *CD = new double[n]; std::fill(CD, CD+n, 0.0);
while (time_flag == 0){
for (int i = 0; i < N; i++)
for(int z = 0; z < m; z++)
for(int x = 0; x < n; x++)
for(int c = 0; c < n; c++){
CD[c] = C[z]*D[x];
C[z] = CD[c] + D[x];
}
iteration_number_local++;
if ((omp_get_wtime() - total_clock) >= time_limit)
time_flag = 1;
}
#pragma omp critical
std::cout<<"I am "<<thread_id<<" and I got" <<iteration_number_local<<"iterations."<<std::endl;
}
}
Я хочу еще раз подчеркнуть, что этот код только игрушка-пример, чтобы попытаться увидеть ускорение: первый для цикла становится короче, когда число параллельных потоков увеличивается (поскольку N уменьшается).
Однако, когда я иду от 1 до 2-4 потоков, число итераций удваивается, как ожидалось; но это не тот случай, когда я использую 8-10-20 потоков: количество итераций не увеличивается линейно с количеством потоков.
Не могли бы вы помочь мне в этом? Правильно ли код? Должен ли я ожидать почти линейного ускорения?
Результаты
Выполнение кода выше, я получил следующие результаты.
1 нить: 23 итерации.
20 потоков: 397-401 итераций на резьбу (вместо 420-460).
Какое оборудование вы используете? Пожалуйста, обратите внимание на процессор (ы) и память. Какая версия и параметры компилятора и какая операционная система? Сколько итераций вы наблюдаете? – Zulan
Проблемные проблемы в ваших измерениях: 'CD' никогда не используется, поэтому компилятор может просто оптимизировать все, что вы ожидаете, дорого. Вы должны хотя бы вывести все 'iteration_number_local' (используйте' pragma omp критический'). – Zulan
Я запускаю код на аппаратном обеспечении с двумя 10-ядерными процессорами Intel Xeon-E5 (так, у меня всего 20 ядер) с 256 ГБ оперативной памяти. Операционная система - Linux. Я не знаю о компиляторе: загружаю модуль под названием «gsl 1.15», а cmake вызывает компилятор под названием «icc». Я думаю, что это не то, что вы просили, пожалуйста, уточните меня лучше. Я запускаю несколько быстрых симуляций с n = 1000, m = 200. С 1thread я получаю 3 итерации за 120 секунд. С двумя нитями я получаю 5 итераций на поток (вместо 6). С 20 потоками я получаю от 40 до 44 итераций на поток (вместо 60!). – Mobius88