Не уверен, как объяснить некоторые из результатов производительности моего кода распараллеленного матричного умножения

Я запускаю этот код в OpenMP для умножения матриц и измерил его результаты:

#pragma omp for schedule(static)
for (int j = 0; j < COLUMNS; j++)
    for (int k = 0; k < COLUMNS; k++)
        for (int i = 0; i < ROWS; i++)
            matrix_r[i][j] += matrix_a[i][k] * matrix_b[k][j];

Существуют разные версии кода, основанные на том, куда я положил#pragma omp директива - перед циклом j, циклом k или циклом i. Кроме того, для каждого из этих вариантов я запускал разные версии для статического планирования по умолчанию, статического планирования с блоками 1 и 10 и динамического планирования с теми же блоками. Я также измерил количество обращений к DC, пропусков DC, тактовых импульсов процессора, удаленных команд и других показателей производительности в CodeXL. Вот результаты для матрицы размером 1000x1000 на AMD Phenom I X4 945:

Результаты измерений производительности

кудаmultiply_matrices_1_dynamic_1 это функция с#pragma omp перед первым циклом и динамическим планированием с чанком 1 и т. д. Вот некоторые вещи, которые я не совсем понимаю о результатах и ​​буду признателен за помощь:

Статическая версия по умолчанию с распараллеливанием перед внутренним циклом выполняется за 2,512 с, а последовательная версия - за 31 683 с - несмотря на то, что она работает на 4-ядерном компьютере, поэтому я предположил, что максимально возможное ускорение будет в 4 раза. Логически возможно, чтобы это произошло, или это какая-то ошибка? Как я могу это объяснить?CodeXL говорит, что 3-я версия со статическим планированием имеет гораздо меньшее количество обращений к DC (и пропусков), чем другие версии. Это почему? Разве это не во многом потому, что все параллельные потоки работают в одной и той же ячейке матрицы b. Это оно?Я знаю, что 2-я версия неверна из-за того, что потоки могут работать в одной и той же ячейке матрицы R, что может вызвать условия гонки. Почему у него более низкая производительность? Неправильно ли это как-то вызвано?Я понимаю, что динамическое планирование приводит к накладным расходам, поэтому код замедляется при его использовании. Кроме того, с 3-й версией (с прагмой перед циклом i) планирование выполняется много раз (миллиард раз с матрицей 1000x1000), поэтому алгоритм намного менее производительный. Однако, это планирование не вызывает замедления во 2-й версии (с прагмой перед 2-м циклом). Это почему?

Кроме того, меня смущает связь пропусков TLB с пропусками в кеше. Когда DTLB используется специально? В документе моего профессора говорится, что каждый доступ к DC является запросом DTLB, но я не понимаю, как это работает - число пропусков TLB часто превышает количество обращений к DC. Как рассчитать коэффициент пропусков TLB? Мой профессор говорит, что это TBL пропуски / доступы DC. Он также говорит, что я могу вычислить временную локальность по коэффициенту попадания в кэш, а пространственную локальность - по коэффициенту попадания в TLB. Как это работает точно?

Ответы на вопрос(2)

Ваш ответ на вопрос