ROOT и OpenMp
………………..
………………..
………………..
# User specific aliases and functions
export ROOTSYS=/cvmfs/hybrilit.jinr.ru/sw/root
export PATH=$PATH:$ROOTSYS/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ROOTSYS/lib
Далее, чтобы получить доступ к OpenMP в макрос пользователя необходимо добавить
Ниже приведен код макроса, в котором происходит розыгрыш случайного числа, вычисления с этим числом и заполнение гистограмм
#include «TROOT.h»
#include «TH1F.h»
#include «TRandom.h»
#include «TCanvas.h»
#include «TFrame.h»
#include «TDatime.h»
#include «TF1.h»
#include «TFile.h»
#include «TStopwatch.h»
#include <iostream>
#include <omp.h>
using namespace std;
int main(){
gROOT->Time();
TStopwatch timer;
Int_t nHist=48;
Long64_t n=10000000;
TH1F *fH1F[48];
Int_t i,j;
Double_t y;
TRandom *fRandom=new TRandom();
TFile *f=new TFile(«ompYes.root»,»recreate»);
cout<<»max threads=»<<omp_get_max_threads()<<endl;
timer.Start();
for(i=0;i<nHist;i++){
fH1F[i] = new TH1F(Form(«hpx%d»,i),»The px distribution»,200,0,200);
}
#pragma omp parallel for shared(fH1F) private(j,i)
for(i=0;i<nHist;i++){
for(j=0;j<n;j++){
Double_t x=fRandom->Gaus(0.,i+1.);
y=sqrt(x*x*x*x+x*x+1)-cos(x+5)*sin(x-5);
fH1F[i]->Fill(y);
}
}
f->Write();
timer.Stop();
cout<<»time: «;
timer.Print(«m»);
f->Close();
return 0;
}
Для компиляции макроса необходимо выполнить команду
При успешной компиляции образуется исполняемый бинарный файл. По умолчанию имя бинарного файла — a.out. Подробно о том, как запускать OpenMP-приложения на кластере hybrilit можно посмотреть здесь.Здесь приведем рекомендуемый вид script-файла, например, с 12-ю потоками:
#SBATCH -p cpu
#SBATCH -c 12
#SBATCH t 60
export OMP_NUM_THREADS=12
export OMP_PLACES=cores
./a.out
Для запуска приложения используется следующая команда:
Следует отметить, что используя OpenMP можно легко распараллелить арифметические операции, встречающиеся в макросах. Специфические же методы пакета ROOT часто не допускают распараллеливания с помощью этой технологии. Например, классы TTree и TFile не являются потокобезопасными, поскольку манипулируют глобальными данными, и не все эти данные полностью защищены для обеспечения безопасности потоков.Поэтому объекты этих классов не должны использоваться совместно (без блокировки) между потоками. Однако можно создать несколько объектов TFile (и, следовательно, объектов TTree), считывая один и тот же физический файл. Следует учитывать тот факт, что на образование потоков тоже расходуется время. Может случиться так, что выйгрыш во времени от работы программы на нескольких потоках будет меньше, чем время, потраченное на образование потоков. Использование OpenMP оправдано только лишь в том случае, если в каждом потоке выполняется значительное количество арифметических операций. В ином случае для распараллеливания программы предпочтительнее использовать PROOF. По этой ссылке можно найти пример (скачать файл), в котором сравнивается эффективность распараллеливания программ с помощью OpenMP и PROOF.