Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[54.226.226.30] |
|
Сообщ.
#1
,
|
|
|
Здравствуйте, вообщем пытаюсь использовать Openmp, чтобы распараллелить задачу вычисления экспоненты с помощью ряда Тейлора. Программа работает, но при сравнении времени выполнения последовательного кода и с Openmp, нет прироста скорости, а даже наоборот выполняется дольше с Openmp. В чем может быть причина, не могли бы вы помочь?
#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 - время выполнения последовательного кода |
Сообщ.
#2
,
|
|
|
Накладные на создание потоков велики. На 32-ух итерациях они не окупятся.
|
Сообщ.
#3
,
|
|
|
Слишком крохотные времена для функций. Попробуйте искусственно удлинить fact(), чтобы проверить действие распараллеливания. Можно прибавлять 2, а вычитать длиннющий ряд 1 + 1/2 + 1/4 + ... или что-то ещё такое.
|
Сообщ.
#4
,
|
|
|
Топорнейшим образом переписал вот так:
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; } } e^x = 7.873127 Time: 0.000012 ... e^x = 7.873127 Time: 0.000005 |
Сообщ.
#5
,
|
|
|
Qraizer, так всё ж "наоборот"! Не в 32 итерациях суть, а в мощности каждой из них. Если их хоть 8, или 3, и каждая будет работать по часу, то и выигрыш будет в разы! А если их хоть миллион, но каждая длится миллисекунды, то перещёлкивание потоков всё (выигрыш) и съест. Или как?..
|
Сообщ.
#6
,
|
|
|
Можно и так сказать. Только алгоритм на секунды не перепишешь, а итераций можно добавить.
|
Сообщ.
#7
,
|
|
|
если хочется выжать максимум из железа, то использование опенмп - плохая затея. только ручками и только с глубоким пониманием сабжа. на малых затратах итерации делить на потоки - организация потока, кэш, ух.... а с опенмп еще надо постоянно анализировать потоки в потоках
|
Сообщ.
#8
,
|
|
|
Цитата _lcf_ @ если хочется выжать максимум из железа, то использование опенмп - плохая затея. только ручками и только с глубоким пониманием сабжа. на малых затратах итерации делить на потоки - организация потока, кэш, ух.... а с опенмп еще надо постоянно анализировать потоки в потоках В каждом предложении не хватает завершения мысли в виде "потому что ..." |
Сообщ.
#9
,
|
|
|
а что там завершать? опенмп топорнейший инструмент, который тупо делит указанные части кода на потоки, нисколько не анализируя и не оптимизируя затраченное время и нагрузку процов. банальное гетнампроц и крэйттрид делает по сути то же самое я бы сказал это инструмент для начинающих/ленивых
|
Сообщ.
#10
,
|
|
|
Цитата _lcf_ @ нисколько не анализируя и не оптимизируя затраченное время и нагрузку процов А смысл у операционной системы забирать ее функции? Планирование загрузки процов - это же прерогатива ОС, не? Конечно можно насильно вязать нити к ядрам, но что это даст в профите? Я понимаю, если в пуле создаваемых нитей нагрузка (по времени) распределена неравномерно, тогда да. А если равномерно? |