Сокращение времени вращения в OpenMP параллельно для - PullRequest
0 голосов
/ 24 января 2019

Мы пишем приложение, критичное к производительности, которое имеет 3 основных параметра: N_steps (около 10000) N_nodes (от 20 до 5000) N_size (диапазон около 1k-10k)

Алгоритм по существу имеет такую ​​форму

for (int i=0; i<N_steps; i++)
{
    serial_function(i); 
    parallel_function(i,N_nodes);
}

, где

parallel_function(i,N_nodes) {
    #pragma omp parallel for schedule (static) num_threads(threadNum)
    for (int j=0; j<N_nodes j++)
    {
        Local_parallel_function(i,j) //complexity proportional to N_size
    }
}

и Local_parallel_function - это функция, выполняющая линейную алгебру, и обычно она имеет время выполнения около 0,01-0,04 секунды или даже больше, и это время выполнения должно быть довольно стабильным в цикле. К сожалению, проблема носит последовательный характер, поэтому я не могу написать внешний цикл по-другому.

Я заметил во время профилирования, что в функции NtYieldExecution тратится огромное количество времени (до 20%, если я использую HT на 4 ядрах).

Я провел несколько тестов, играя с параметрами, и обнаружил, что этот процент:

  • Увеличивается с количеством потоков

  • Уменьшается по мере увеличения N_nodes и N_size.

Скорее всего, для OpenMP параллельный цикл в настоящее время недостаточно велик, и его уменьшение или более дорогая в вычислительном отношении функция помогает сократить эти издержки.

Чтобы лучше понять, я скачал Intel Profiler и получил следующие результаты:

Results from V Tune-1 Results from V Tune-2

Область, выделенная красным, - это время вращения, а потоки сверху - это те, которые были созданы OpenMP.

Есть предложения о том, как управлять и уменьшить этот эффект?

Я использую Windows 10, Visual Studio 15.9.5 и OpenMP. К сожалению, похоже, что Intel Compiler не может скомпилировать одну зависимую библиотеку, поэтому я застрял с Microsoft.

...