Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум на Исходниках.RU > C/C++: Общие вопросы > Распараллеливание с помощью openmp |
Автор: shonny 14.11.17, 16:57 |
Здравствуйте, вообщем пытаюсь использовать Openmp, чтобы распараллелить задачу вычисления экспоненты с помощью ряда Тейлора. Программа работает, но при сравнении времени выполнения последовательного кода и с Openmp, нет прироста скорости, а даже наоборот выполняется дольше с Openmp. В чем может быть причина, не могли бы вы помочь? <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> #include <stdio.h> #include <stdlib.h> #include <math.h> #include <omp.h> int fact(int c); double taylor(double x, int n); int main(int argc, char *argv[]) { double x=0; int n=0; int n_max = 32; if (argc != 3) { printf("Input three parametrs!\n"); return 1; } sscanf(argv[1], "%lf", &x); sscanf(argv[2], "%d", &n); if((n>n_max)||(n<0)) { printf("Invalid parameter n, enter n from 0..10\n"); return 1; } int i; double sum=0 ; double t = omp_get_wtime(); #pragma omp parallel for private(i) reduction(+: sum) for (i=1; i<=n; i++) { double taylor = pow(x,i)/fact(i); sum+=taylor; } double diff = omp_get_wtime() - t; printf("e^x = %lf\n Time: \t %lf\n", ++sum, diff); return 0; } int fact(int c) { int fact=1; int i; for (i = 1; i <= c; i++ ) { fact *=i; } return fact; } ./taylor 1 32 e^x = 2.718282 Time: 0.000126 - время выполнения с openmp /staylor 1 32 e^x = 2.718282 Time: 0.000020 - время выполнения последовательного кода |
Автор: Qraizer 14.11.17, 17:17 |
Накладные на создание потоков велики. На 32-ух итерациях они не окупятся. |
Автор: Славян 14.11.17, 17:23 |
Слишком крохотные времена для функций. Попробуйте искусственно удлинить fact(), чтобы проверить действие распараллеливания. Можно прибавлять 2, а вычитать длиннющий ряд 1 + 1/2 + 1/4 + ... или что-то ещё такое. |
Автор: Qraizer 14.11.17, 18:20 |
Топорнейшим образом переписал вот так: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> чтобы время создания не учитывалось, получил: double t; #pragma omp parallel private(i) reduction(+: sum) { for (i=1; i<=n; i++) { double taylor = pow(x,i)/fact(i); sum+=taylor; } sum = 0; t = omp_get_wtime(); for (i=1; i<=n; i++) { double taylor = pow(x,i)/fact(i); sum+=taylor; } } <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> Но всё равно, 32 итерации – это крайне мало для накопления статистики. На отклонение будут влиять малейшие чихи ОС, включая асинхронные прерывания от сетевухи. e^x = 7.873127 Time: 0.000012 ... e^x = 7.873127 Time: 0.000005 |
Автор: Славян 14.11.17, 19:12 |
Qraizer, так всё ж "наоборот"! Не в 32 итерациях суть, а в мощности каждой из них. Если их хоть 8, или 3, и каждая будет работать по часу, то и выигрыш будет в разы! А если их хоть миллион, но каждая длится миллисекунды, то перещёлкивание потоков всё (выигрыш) и съест. Или как?.. |
Автор: Qraizer 14.11.17, 20:15 |
Можно и так сказать. Только алгоритм на секунды не перепишешь, а итераций можно добавить. |
Автор: _lcf_ 14.11.17, 20:26 |
если хочется выжать максимум из железа, то использование опенмп - плохая затея. только ручками и только с глубоким пониманием сабжа. на малых затратах итерации делить на потоки - организация потока, кэш, ух.... а с опенмп еще надо постоянно анализировать потоки в потоках |
Автор: JoeUser 15.11.17, 03:28 |
Цитата _lcf_ @ если хочется выжать максимум из железа, то использование опенмп - плохая затея. только ручками и только с глубоким пониманием сабжа. на малых затратах итерации делить на потоки - организация потока, кэш, ух.... а с опенмп еще надо постоянно анализировать потоки в потоках В каждом предложении не хватает завершения мысли в виде "потому что ..." |
Автор: _lcf_ 15.11.17, 08:03 |
а что там завершать? опенмп топорнейший инструмент, который тупо делит указанные части кода на потоки, нисколько не анализируя и не оптимизируя затраченное время и нагрузку процов. банальное гетнампроц и крэйттрид делает по сути то же самое я бы сказал это инструмент для начинающих/ленивых |
Автор: JoeUser 15.11.17, 13:02 |
А смысл у операционной системы забирать ее функции? Планирование загрузки процов - это же прерогатива ОС, не? Конечно можно насильно вязать нити к ядрам, но что это даст в профите? Я понимаю, если в пуле создаваемых нитей нагрузка (по времени) распределена неравномерно, тогда да. А если равномерно? |