Обратите внимание, что все, что я описываю, зависит от реализации.
Можно ли ограничить количество потоков в цикле openmp for?
Да.Есть разные способы сделать это.Установите omp_set_nested(1);
и используйте что-то вроде #pragma omp parallel for num_threads(4)
или аналогичное во внешнем цикле и директиву #pragma omp parallel for num_threads(2)
во внутреннем цикле.Это должно дать вам 8 потоков (в зависимости от реализации вам, возможно, также придется установить OMP_THREAD_LIMIT
, если у вас менее 8 ядер)
В качестве альтернативы, вы можете вручную развернуть свои циклы, например, используя что-то вроде
#pragma omp parallel sections {
#pragma omp section
do your stuff for the first part, nest parallel region again
#pragma omp section
and so on for the other parts
}
Вы можете сделать то же самое иногда более эффективно в OpenMP 3.0 с помощью #pragma omp task
.
Или вы запускаете 8 потоков и получаете номер текущего потока в параллельном разделе и планируете вручную на основеномер потока.
Наконец, если у вас есть идеально вложенный цикл (цикл идеально вложен, если фактическое назначение происходит только в самом внутреннем цикле), вы можете переписать все в один цикл.В основном, упакуйте два итератора i
и j
в один большой итератор (i, j)
.Обратите внимание, что это может уменьшить локальность и, следовательно, снизить производительность
Является ли этот многоуровневый параллелизм чем-то, что на практике имеет смысл?
Это зависит, и вы должны выяснить,сам.В целом, многоуровневый параллелизм делает вашу проблему более масштабируемой.Планирование, однако, может быть более сложным.Эта бумага может быть интересной.
Относительно установки количества потоков вручную: главное преимущество установки количества потоков состоит в том, что вы можете использовать конкретные знания о вашей проблеме при планировании.Таким образом, вы можете уменьшить накладные расходы и получить более высокую локальность исполняемого кода и, следовательно, больше обращений к кешу и меньше операций ввода-вывода в основной памяти.
Основной недостаток ручной установки количества потоков во вложенном параллелизме состоит в том, что потокив самом внутреннем цикле может ожидаться бездействующий на неявном барьере, в то время как дополнительная работа могла бы быть сделана ( пример ).Кроме того, грубый параллелизм плохо масштабируется.Поэтому, если ваш внешний цикл имеет очень разное время выполнения в цикле, вы хотите более гибко планировать, чем просто разделение на 4 потока.
Любые другие мысли
Хотели ли вы сделать MxV с SIMD?В зависимости от архитектуры, это может дать ускорение 2-4.Я быстро прогуглил для вас эту презентацию .
Для MxV, разбиение на петли , регистрация и блокировка кэша и связанные с ними методы могут увеличить локальность данных иуменьшить другие проблемы, например, ложный обмен.Эта книга , глава 11 (вы можете просмотреть ее), может дать вам некоторые дополнительные идеи о том, как реструктурировать доступ к данным.