OpenMP бенчмаркинг параллельных вычислений - PullRequest
0 голосов
/ 04 октября 2019

Я пытаюсь провести сравнительный анализ вычислений f(x), изменяя количество потоков на каждой итерации.

f (x) = c * ln (x) * cos (x)

n = 10000000


for (int pp = 2; pp<17; pp++)
{
    p = pp;
    int chunk = n/p; //acts like floor
    omp_set_num_threads(p);
    double start_parallel = omp_get_wtime();
    //start parallel
    #pragma omp parallel shared(tt,chunk) private (i)
    {
        //printf("thread number %d\n",omp_get_thread_num());
        #pragma omp for schedule(dynamic,chunk) nowait
        for(i=0; i<n; i++)
        {
            //tt[i] = f(tt[i]);
            tt[i] = f1(tt[i]); //the speed up is much higher with f1 since log and cos 
                               //computations are polynomial; see function.
        }
    } //end parallel
    double end_parallel = omp_get_wtime();
    double cpu_time_used_parallel = (double) (end_parallel - start_parallel);
    printf("parallel: for n=%d, p=%d, time taken=%f, speedup=%f\n",
            n,p,cpu_time_used_parallel,
            cpu_time_used_seq/cpu_time_used_parallel);
}

Результат:

Запущены переменные потоки:

параллельно: для n = 10000000, p = 2, затраченное время = 0.153774, ускорение = 3.503831

параллельный: для n = 10000000, p = 3, затраченное время = 0,064447, ускорение = 8,360370

параллельный: для n = 10000000, p = 4, затраченное время = 0,044694, ускорение = 12,055239

параллель: для n = 10000000, p = 5, время взято = 0.048700, ускорение = 11.063550

параллель: для n = 10000000, p = 6, время взято = 0.039009, ускорение = 13.811989

параллельный: для n = 10000000, p = 7, затраченное время = 0,041735, ускорение = 12,910017

параллельный: для n = 10000000, p = 8, затраченное время = 0,041268, ускорение = 13,055919

параллельный: для n = 10000000, p = 9, затраченное время = 0.039032, ускорение = 13.804157

параллельный: для n = 10000000, p = 10, затраченное время = 0.038970, ускорение = 13.825767

параллельно: для n = 10000000, p = 11, время выполнения = 0,039843, ускорение = 13,522884

параллель: для n = 10000000, p = 12, время = 0,041356, ускорение = 13,028237

параллель: для n = 10000000, p = 13, время = 0,041039, ускорение = 13,128763

параллельно: для n = 10000000, p = 14, время = 0,047433, ускорение = 11,359218

параллельно: для n = 10000000, p = 15, время = 0,048430, ускорение = 11,125202

параллельный: для n = 10000000, p = 16, затраченное время = 0,051950, ускорение = 10,371477


Примечание: Ускорение здесь рассчитывается по последовательному алгоритму(threads = 1)

Кажется, что на ускорение не влияет изменение p (количество потоков).

Я делаю это правильно, или причина кроется в неэффективном увеличении числа потоков (то есть теоретически изменение p не окажет серьезного влияния на O(myprogram))?

Ответы [ 2 ]

2 голосов
/ 06 октября 2019

Q : Я правильно делаю ...?
A : Нет, извините, вы неслучилось сделать это правильно. Давайте проанализируем причины и давайте наметим несколько советов по сравнительному тестированию производительности класса HPC:

Ну, вы уже знаете, что первоначальный дизайн эталонного теста не был хорошо продуман. Влияние дополнительных расходов, продемонстрированное в современной критике оригинала , наивно-наивного закона Амдаля , содержит более подробную информацию об этом , и детали синхронизации показываютЭто очень хорошо, поскольку затраты на создание экземпляров все меньше и меньше по сравнению с другими классами обработки и связанные с вводом / выводом затраты, как показано ниже.

enter image description here

Причины?

Код имеет огромные дополнительные издержки по сравнению с частью "вычисления". Это самый сильный маркер некорректного использования технологических возможностей конструктора синтаксиса, в противном случае допустимого (OpenMP здесь, map-Reduce где-то в другом месте, списочное понимание в других случаях или некоторые другие приемы синтаксического suger в другом месте)

Конечная производительность - это Искусство балансирования (правильное соотношение затрат и выгод - любой дисбаланс означает потерю производительности).


Затраты? Вот? Посмотрите на картину результатов ::

Вторым грехом было игнорирование штрафа за сценой [TIME] -домен за масштабирование [SPACE] -доменов. Чем больше n, тем больше памяти должно было быть выделено, и тем больше штрафов приходилось на (ужасающую) неэффективность строк кэша, все это с нулевой защитой от попадания в ад памятизамена:

n=1E3        1E4        1E5        1E6        1E7        1E8        1E9       :
______________________________________________________________________________:_____
1.000      1.000      1.000      1.000      1.000      1.000      1.000       : p= 1
0.930      1.403      0.902      1.536      1.492      1.517      0.356       : p= 2
1.075      2.319      2.207      1.937      2.001      1.991      1.489++     : p= 3
1.497+++++ 2.636++++  1.563      1.657      2.571      2.144      0.687       : p= 4
1.226++    2.548+++   0.957      2.025      2.357      1.731      1.569++++   : p= 5
1.255+++   1.805      2.704      2.020      2.348      1.502      0.989       : p= 6
0.957      0.581      3.104++    2.124      2.486      2.002      0.838       : p= 7
1.151      1.376      2.449      2.154      2.573      1.536      0.776       : p= 8
1.135      1.685      2.388      2.506+++   2.852++++  2.311      1.676+++++  : p= 9
1.285++++  2.492++    2.497      2.568++++  2.647+     2.467      1.413+      : p=10
1.177      2.314+     2.709+     2.174      2.688+++   2.634++++  0.606       : p=11
1.216+     2.293      2.442      2.287      2.550      2.551++    1.256       : p=12
1.034      2.148      1.802      2.361++    2.635      2.554+++   1.181       : p=13
0.999      0.440      3.672+++++ 2.774+++++ 2.927+++++ 2.839+++++ 1.496+++    : p=14
1.091      1.217      3.285++++  2.284      2.525      2.356      1.005       : p=15
0.937      2.850+++++ 3.185+++   2.334+     2.655++    2.508+     0.889       : p=16

Советы по улучшению производительности?

  • Если вы сравните результаты вычислений, сравните результаты вычислений и избегайте MEM-I / O

  • При сравнительном тестировании всегда проверяйте весь ландшафт, чтобы чувствовать ( лучше научиться избегать / исключать любое такое искажение результатов измерений) в кеше побочные эффекты

  • Always избегать любых формсовместное использование (можно избежать - сопоставьте обработку по разрозненным областям tt[], но при этом охватывая «весь» tt[], в связных блоках строки кэша, чтобы избежать ложного совместного использования и «припо крайней мере "повторно использовать любые данные из уже полученных блоков данных, которые вы оплатили расходы на MEM-I / O fetching уже (если векторное LOAD / STORE действительно необходимо - см. выше)

  • Разрешить и активно использовать любые приемы HPC-векторизации, доступные с FMA4 / SIMD / AVX512

0 голосов
/ 04 октября 2019

Ваши результаты неверны из-за условия nowait в прагме omp. Обычно конец parallel представляет точку синхронизации, но без ожидания первый завершающий поток не будет ожидать других потоков, поэтому вы выполните double end_parallel = omp_get_wtime();, пока другие потоки все еще выполняют некоторые вычисления. Если вы достанете nowait, вы должны наблюдать совершенно разные результаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...