Распараллеливание маленького массива медленнее, чем распараллеливание большого массива? - PullRequest
0 голосов
/ 26 января 2020

Я написал небольшую программу, которая генерирует случайные значения для двух значений, а в для l oop значения указанных массивов добавляются к новому.

Однако, когда я использую небольшой размер массива (20 элементов), параллельная версия занимает значительно больше времени, чем последовательная, а когда я использую большие массивы (200 000 элементов), она занимает примерно столько же времени (параллель всегда немного медленнее).

Почему это так? Единственная причина, по которой я могу думать, заключается в том, что при большом массиве ЦП помещает его в кэш-память третьего уровня и распределяет его по всем ядрам, тогда как при работе с маленьким массивом его приходится копировать с более низким уровнем кеша? Или я ошибаюсь?

Вот код:

#include <valarray>
#include <iostream>
#include <ctime>
#include <omp.h>
#include <chrono>

int main()
{
    int size = 2000000;
    std::valarray<double> num1(size), num2(size), result(size);
    std::srand(std::time(nullptr));
    std::chrono::time_point<std::chrono::steady_clock> start, stop;
    std::chrono::microseconds duration;

    for (int i = 0; i < size; ++i) {
     num1[i] = std::rand();
     num2[i] = std::rand();
    }

    //Parallel execution
    start = std::chrono::high_resolution_clock::now();
#pragma omp parallel for num_threads(8)
    for (int i = 0; i < size; ++i) {
        result[i] = num1[i] + num2[i];
    }
    stop = std::chrono::high_resolution_clock::now();
    duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
    std::cout << "Parallel for loop executed in: " << duration.count() << " microseconds" << std::endl;

    //Serial execution
    start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < size; ++i) {
        result[i] = num1[i] + num2[i];
    }
    stop = std::chrono::high_resolution_clock::now();
    duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
    std::cout << "Serial for loop executed in: " << duration.count() << " microseconds" << std::endl;
}

Вывод с size = 200 000

Parallel for loop executed in: 2450 microseconds
Serial for loop executed in: 2726 microseconds

Вывод с size = 20

Parallel for loop executed in: 4727 microseconds
Serial for loop executed in: 0 microseconds

Я использую Xeon E3-1230 V5 и компилирую с помощью компилятора Intel, используя максимальную оптимизацию и оптимизацию Skylake c.

Я получаю идентичные результаты с Visual Studio Компилятор C ++.

...