Wyodrębniłem tę prostą funkcję członka z większego programu 2D, wszystko, co robi, to pętla for uzyskująca dostęp z trzech różnych tablic i wykonująca operację matematyczną (splot 1D). I zostały badania z użyciem OpenMP, aby ta szczególna funkcja szybciej:Dlaczego ta pętla nie działa szybciej przy użyciu OpenMP?
void Image::convolve_lines()
{
const int *ptr0 = tmp_bufs[0];
const int *ptr1 = tmp_bufs[1];
const int *ptr2 = tmp_bufs[2];
const int width = Width;
#pragma omp parallel for
for (int x = 0; x < width; ++x)
{
const int sum = 0
+ 1 * ptr0[x]
+ 2 * ptr1[x]
+ 1 * ptr2[x];
output[x] = sum;
}
}
Jeśli używam gcc 4.7 na debian/wheezy amd64 ogólna programowe wykonuje dużo wolniej na maszynie 8 procesorów. Jeśli używam gcc 4.9 na debian/jessie amd64 (tylko 4 procesory na tym komputerze) ogólny program działa z bardzo niewielką różnicą.
Korzystanie time
porównać: pojedynczy bieg rdzeń:
$ ./test black.pgm out.pgm 94.28s user 6.20s system 84% cpu 1:58.56 total
wielo prowadzony rdzeń:
$ ./test black.pgm out.pgm 400.49s user 6.73s system 344% cpu 1:58.31 total
Gdzie:
$ head -3 black.pgm
P5
65536 65536
255
Więc Width
jest ustawiony na 65536
w trakcie realizacji.
przypadku tej sprawy, używam cmake do kompilacji:
add_executable(test test.cxx)
set_target_properties(test PROPERTIES COMPILE_FLAGS "-fopenmp" LINK_FLAGS "-fopenmp")
I CMAKE_BUILD_TYPE jest ustawiony na:
CMAKE_BUILD_TYPE:STRING=Release
co oznacza -O3 -DNDEBUG
Moje pytanie, dlaczego jest to for
pętla nie szybciej przy użyciu wielordzeniowych? W macierzy nie ma nakładania się, openmp powinien równo dzielić pamięć. Nie wiem, skąd się bierze wąskie gardło?
EDIT: jak to pisano, zmieniłem plik wejściowy:
$ head -3 black2.pgm
P5
33554432 128
255
Więc Width
jest teraz ustawiony na 33554432
trakcie realizacji (powinny być uważane za mało). Teraz czas ujawnia:
pojedynczy bieg rdzeń:
$ ./test ./black2.pgm out.pgm 100.55s user 5.77s system 83% cpu 2:06.86 total
wielo prowadzony rdzeń (z jakiegoś powodu cpu% była zawsze poniżej 100%, które wskazują na brak tematów w ogóle):
$ ./test ./black2.pgm out.pgm 117.94s user 7.94s system 98% cpu 2:07.63 total
ogólnie, nieprawdziwe współdzielenie/zablokowanie rywalizacji. Jak duża jest "szerokość"? – sehe
@ sorry, zapomniałem o tym wspomnieć. – malat
Jak to przetestowałeś? Wątpię, żeby pojedyncza pętla 64k, którą dałeś, zabierała tyle czasu. – ElderBug