24.12.2008 в 22:01 — Misha
Поделитесь опытом:)
Я решаю физические уравнения численными методами. Использую интеловский компилятор. Сравнивал его с gfortran: интеловский процентов на 30% быстрее считает. Вот так поставишь програмку и она недельку считает. А потом оказывается, что забыл параметр нужный установить или ошибка оказывается. Ну в общем, как всегда:))
А вот openmp никак не могу подключить. Делаю всё как в примере, подключаю дирекивы. А он вместо того, чтобы считать в два раза быстрее на двухъядерном процессоре считает в два раза медленнее. У кого-нибудь есть удачный опыт распараллеливания?
Однако, если запустить две программы одновременно, они считаю в два раза быстрее.
Комментарии
А сам пример-то нормально работает ?
Ну если директивы компилятор понял, то по идее openmp вы подключили. Другой вопрос как вы распараллелили, можно так это сделать, что программа будет работать медленнее.
К сожалению у меня только небольшой опыт с gcc
Пример выдаёт правильный результат:)
Директивы компилятор понял и даже сказал, что нашёл цикл, который распараллелил. Я вот тоже думаю, что распараллелить нужно грамотно. Память то всё таки одна и оба процесса к ней обращаются. Но не пойму, почему пример из мануала по openmp тоже считает в два раза медленней. На создание самого процесса нужно ещё пределенное время, но оно порядка 0.1 сек., а время счета программа 80 сек.
А с gcc опыт то положительный? она быстрей считает?
Дык то есть пример из мануала тоже работает не так как ожидалось? А марка проца-то какая?
ЗЫ У меня такое ощущение что можно компилятор заставить выдать промежуточный листинг после отработки openmp, может там посмотреть как распараллелилось?
Вот меня и озадачило, что пример из мануала не так работает.
Я на двух процессорах тестировал: на стареньком P4, но зато с гипертритингом, и на Core 2 Duo двухъядерном.
Листинг, нужно будет посмотреть. Пока ещё не знаю как.
А компилятор какой? Не может компилятор сам оптимизировать так, что быстрее openmp получается?
ЗЫ Я то по старинке через mpi работаю. На p4 ht прирост от второго процесса 10-20 % на core2duo 100 %
Ну опыт пока больше теоретический, до реальных приложений дело не доходило. Но сейчас пишу диплом (трассировку лучей). Планирую mpi-вариант и mpi+openmp сравнить.
Что насчет примеров. Испытывал программку расчета числа пи ():
#include <QTime>
#include "omp.h"
static unsigned long num_steps = 2000000000;
double step;
QTime timer;
int main(int argc, char *argv[])
{
t();
unsigned long i;
double x, pi, sum = 0.0;
step = 1.0/(double) num_steps;
omp_set_num_threads(50);
#pragma omp parallel for private(x) reduction(+:sum)
for (i=0;i<= num_steps; i++){
x = (i+0.5)*step;
sum = sum + 4.0/(1.0+x*x);
}
pi = step * sum;
qDebug("%f %d",pi,sed());
return 0;
}
Результаты такие:
1. при num_steps = 500000000 выигрыша практически нет. При малом числе потоков - вообще медленнее работает. При числе потоков 200-300 выигрыш порядка 50-100 мс
2. при num_steps = 2000000000 все уже по-другому. Однопоточная программа: 194094 мс, 50 потоков: 115836 мс, 100 потоков: 114932, 200 потоков: 112342, 300 потоков: 111173 мс.
Процессор: p4 2.4МГц с ht.
В принципе что и следовало ожидать: создание потока операция затратная.
"На основании изложенного выше можно сделать следующий важный вывод: при выделении параллельных областей программы и разработке параллельных процессов необходимо, чтобы трудоемкость параллельных процессов была не менее 2000 операций деления. В противном случае параллельный вариант программы будет проигрывать в быстродействии последовательной программе. Для эффективной работающей параллельной программы этот предел должен быть существенно превышен."
2Misha Remnev:
А пользуетесь ли какими-нибудь еще средствами от интел? У них там еще есть средства анализа, профайлинга разные (intel thread cheker, intel vtune analyzer).
Я использую tau для профайлинга ().
eclipse+cpp+ptp(parallel tools platform)/pldt+tau все хорошо интегрируется в эклипс. ptp - для mpi.
Я проверял на компиляторах Intel и gfortran. Оба считают медленнее в два раза. Кстати, у компилятора intel есть опция -parallel которая по идее сама должна распараллеливать автоматичеки. Но он на неё почему-то вообще не регирует. У меня дома P4 ht на работает Core 2 Due. Ни на том ни на том прироста нет, только убыль:)
Пример, кстати, на Фортране у меня тоже Пи считает. Ввел те же паремтры - нифига. Что самое нехорошее, то что при разных параметрах, количество потоков или n, он считает одно и то же время.
А как подключить QTime? Я хотел попробовать этот пример на Си, а он ругается, что не знает такого файла. И командную строку для компиляции пожалуйста напишите, а то я с Си никогда не работал:))
Я только компилятором от интела пользуюсь. "intel thread cheker" - судя по названию, это может помочь в распараллеливании.
Прям чудеса у вас, одна убыль )
Насчет QTime и qDebug() - это все qt-шные приблуды. Я на qt программирую просто, поэтому первое попавшееся для замера времени и вывода сунул. Попоробуйте тогда так (без qt):
#include <ctime>
#include <iostream>
#include "omp.h"
static unsigned long num_steps = 500000000;
double step;
clock_t start,end;
int main(int argc, char *argv[])
{
start = clock();
unsigned long i;
double x, pi, sum = 0.0;
step = 1.0/(double) num_steps;
omp_set_num_threads(50);
#pragma omp parallel for private(x) reduction(+:sum)
for (i=0;i<= num_steps; i++){
x = (i+0.5)*step;
sum = sum + 4.0/(1.0+x*x);
}
pi = step * sum;
end = clock();
double elapsed = (double)(end - start)/CLOCKS_PER_SEC;
std::cout<<pi<<" "<<elapsed<<" s\n";
return 0;
}
Потом в консоли (если код находится в , например):
$ g++ -c -fopenmp ./
$ g++ -lgomp ./omp.o -o omp
$ ./omp
Не помню с какой версии gnu компиляторы поддежривают openmp (или 4.2 или 4.3). У меня 4.3.3. Также должна присутствовать библиотека gomp.
Другие продукты intel, доступные для некоммерческого персонального использования - , посмотрите, если интересно ( в частности теже intel thread cheker, vtune analyzer). Они могут помочь при разработки более реальных приложений с использованием intelовского компилятора, да и сейчас вы можете проанализировать с их помощью свои "убыли" )).
Да, а с фортраном вы тоже через консоль работаете? Какие-нибудь среды, тот же eclipse не используете?
Для анализа времени таких вещей лучше применять системный time
time ./omp
О, хороший совет, спасибо, не знал.
Ура, ваш пример без распараллеливания показал 17.8 сек, а с распараллеливанием 9.11 секунды на P4 3000 ht. Очень хорошо. Значит у меня в фортране косяк.
Я через консоль работаю на Фортране. У меня только численные рассчёты - никаких наворотов не нужно. Пользуюсь gedit. Расстраивает меня в нём только то, что нет code folding. Eclipse мне кажется слишком навороченным для моих задач. Он же больше для Java.
А по поводу интеловских утилит, домаю, что они полезны. Хотя пока руки не доходят до их освоения.
Спасибо, за time ./omp - я тоже не знал.
Интересное дело: когда комилирую фортрановскую программу с ключами gfortran -g0 -O3 -fopenmp pi.f90 считает 29.6 сек, когда отключаю openmp и компилирую gfortran -g0 -O3 pi.f90 считает 27.5 сек. Хорошо, что уже столько же считает. А когда копмилирую без ключей gfortran pi.f90 считает 1 мин 21 сек, а когда с openmp gfortran -openmp pi.f90 считатет 37 сек!
Может, он и правда сам распараллеливает. Тогда почему при распараллеливании системный монитор показывает, что заняты оба процессора, а без распараллеливания - один...