OpenMP GCC GOMP расточительный барьер - PullRequest
7 голосов
/ 18 апреля 2011

У меня есть следующая программа.nv - около 100, dgemm - 20x100 или около того, поэтому есть много работы:

#pragma omp parallel for schedule(dynamic,1)
        for (int c = 0; c < int(nv); ++c) {
            omp::thread thread;                                               
            matrix &t3_c = vv_.at(omp::num_threads()+thread);
            if (terms.first) {
                blas::gemm(1, t2_, vvvo_, 1, t3_c);
                blas::gemm(1, vvvo_, t2_, 1, t3_c);
            }

            matrix &t3_b = vv_[thread];
            if (terms.second) {
                matrix &t2_ci = vo_[thread];
                blas::gemm(-1, t2_ci, Vjk_, 1, t3_c);
                blas::gemm(-1, t2_ci, Vkj_, 0, t3_b);
            }
        }

, однако с GCC 4.4, GOMP v1, gomp_barrier_wait_end составляет почти 50% времени выполнения.Изменение GOMP_SPINCOUNT уменьшает накладные расходы, но тогда используются только 60% ядер.То же самое для OMP_WAIT_POLICY=passive.Система Linux, 8 ядер.

Как я могу получить полное использование без вращения / ожидания перегрузки

Ответы [ 2 ]

3 голосов
/ 18 апреля 2011

Барьер - это симптом, а не проблема. Причиной большого ожидания в конце цикла является то, что некоторые потоки выполняются задолго до других, и все они ждут в конце цикла for довольно долго, пока все не закончат.

Это классическая проблема дисбаланса нагрузки, которая здесь странная, поскольку это просто набор умножений матриц. Они разных размеров? Как они расположены в памяти с точки зрения NUMA - все они в настоящее время находятся в кеше одного ядра, или есть другие проблемы с совместным использованием? Или, проще говоря - только 9 матриц, так что оставшиеся 8 обречены застрять в ожидании того, кто получит последний?

Когда подобное происходит в большом параллельном блоке кода, иногда можно перейти к следующему блоку кода, в то время как некоторые из итераций цикла еще не завершены; там вы можете добавить директиву nowait, для которой будет отменено поведение по умолчанию и избавиться от подразумеваемого барьера. Здесь, тем не менее, поскольку параллельный блок имеет размер цикла for, это не может помочь.

2 голосов
/ 20 апреля 2011

Может ли быть, что ваша реализация BLAS также вызывает OpenMP внутри?Если вы не видите только один звонок на gomp_barrier_wait_end.

...