В программе есть большой внешний цикл (~10000 итераций) в который вложены еще некоторые более мелкие циклы с мат вычислениями (~2500 итераций), при попытке раскидать внешний цикл на несколько потоков столкнулись с проблематичной синхронизацией потоков (слишком сильная зависимость между итерациями), поэтому решили «раскидывать» на потоки вложенный цикл.
Но встали перед вопросом чем воспользоваться boost::thread или openMP?
Насчет openMP документации нашел много, и везде указывалось что на разветвление программы и потом обратный сбор уходит довольно много времени (пишут порядка 2000 операций), насчет boost::thread подобных замечаний не нашел. И даже прочитал где-то что мол boost::thread при организации мелких циклов имеет преимущество по производительности по сравнению с openMP. Ну и естественно решил попробовать....
Написал 2 идентичные по объему операций программки:
На openMP:
_______________________________________
#include <iostream>
#include <omp.h>
#include <time.h>
#define Npar 4
#define Nmas 1000
int main(int argc, char* argv[])
{
float* a = new float[Nmas];
float* b = new float[Nmas];
float* c = new float[Nmas];
for (int k = 0; k < 100000; k++)
{
#pragma omp parallel shared(a, b, c) num_threads(Npar)
{
int myid = omp_get_thread_num();
for (int i = myid; i < Nmas; i += Npar)
{
a[i] = (float) i;
b[i] = a[i] * a[i];
c[i] = 0.3 * a[i] - b[i] / a[i];
}
}
}
delete[] a;
delete[] b;
delete[] c;
std::cout << clock() << std::endl;
return 0;
}
_________________________________________
И на boost::thread :
_________________________________________
#include <boost/thread/thread.hpp>
#include <iostream>
#include <time.h>
#define Nmas 1000
#define Npar 4
using namespace std;
void proga(int ind, float* a, float* b, float* c)
{
for (int i = ind; i < Nmas; i += Npar)
{
a[i] = (float) i;
b[i] = a[i] * a[i];
c[i] = 0.3 * a[i] - b[i] / a[i];
}
}
int main(int argc, char* argv[])
{
float* a = new float[Nmas];
float* b = new float[Nmas];
float* c = new float[Nmas];
for (int j = 0; j < 100000; j++)
{
boost::thread my_thread1(&proga, 0, a, b, c);
boost::thread my_thread2(&proga, 1, a, b, c);
boost::thread my_thread3(&proga, 2, a, b, c);
boost::thread my_thread4(&proga, 3, a, b, c);
my_thread1.join();
my_thread2.join();
my_thread3.join();
my_thread4.join();
}
delete[] a;
delete[] b;
delete[] c;
std::cout << clock() << endl;
return 0;
}
________________________________________
Компилятор g++-4.3, ОС Kubunta 9.04,
проц. CPU Intel Core 2 Quad Q8300 2.5ГГц.
Откомпилил обе проги запустил проверить кто же быстрее и на сколько, и в ответ получил замечательные данные:
(программы запускал по 10 раз каждую привожу средние данные)
по данным ф-ции clock():
boost 8700000 (8.7c)
openMP 8800000 (8.8c)
по данным ф-ции time:
boost
real 0m8.588s
user 0m4.616s
sys 0m4.176s
__________________
openMP
real 0m7.438s
user 0m6.828s
sys 0m3.132s
__________________
В сфязи с чем у меня возникает 4 вопроса:
1. кому верить time или clock???
2. так кто же быстрее boost или openMP???
3. для каких случаев обычно используют тот или другой метод распараллеливания???
4. может я что-то не так делаю?