Проблема с эталоном: время выполнения варьируется между двумя значениями

Я пытаюсь сравнить три разных приложения. Все они написаны на C ++ с использованием MPI и OpenMP и скомпилированы с gcc7.1 и OpenMPI3.0. Я использую кластер с несколькими узлами и 2 процессорами Intel с 24 ядрами. На каждом узле выполняется один процесс, и на каждом узле распараллеливание выполняется с помощью OpenMP.

Изменить: Это самый короткий тест, я тестировал пользовательские операции сокращения:

#include <mpi.h>
#include <omp.h>
#include <vector>
#include <chrono>

int process_id = -1;

std::vector<double> values(268435456, 0.1);

void sum(void *in, void *inout, int *len, MPI_Datatype *dptr){
double* inv = static_cast<double*>(in);
double* inoutv = static_cast<double*>(inout);
*inoutv = *inoutv + *inv;
}

int main(int argc, char** argv) {
MPI_Init(&argc, &argv);
int mpi_world_size = 0;
MPI_Comm_size(MPI_COMM_WORLD, &mpi_world_size);
MPI_Comm_rank(MPI_COMM_WORLD, &process_id);

#pragma omp declare reduction(sum : double : omp_out = omp_out + omp_in) initializer(omp_priv = omp_orig)

MPI_Op sum_mpi_op;
MPI_Op_create( sum, 0, &sum_mpi_op );
double tmp_result = 0.0;
double result = 0.0;

std::chrono::high_resolution_clock::time_point timer_start = std::chrono::high_resolution_clock::now();

#pragma omp parallel for simd reduction(sum:tmp_result)
for(size_t counter = 0; counter < 268435456; ++counter){
tmp_result = tmp_result + values[counter];
}

MPI_Allreduce(&tmp_result, &result, sizeof(double), MPI_BYTE, sum_mpi_op, MPI_COMM_WORLD);
std::chrono::high_resolution_clock::time_point timer_end = std::chrono::high_resolution_clock::now();
double seconds = std::chrono::duration<double>(timer_end - timer_start).count();

if(process_id == 0){
printf("Result: %.5f; Execution time: %.5fs\n", result, seconds);
}

MPI_Finalize();
return EXIT_SUCCESS;
}

Я заметил, что время выполнения для всех тестов варьируется между двумя значениями, например, для теста A у меня 10 пробежек, 5 — около 0,6 с, а 5 — около 0,73 (+/- немного).
Для Benchmark B это то же самое, но время исполнения составляет 77 с или 85 с (снова +/-).
Эквивалентные результаты для Benchmark C. Таким образом, между ними нет ничего.
Я измеряю время с помощью std :: chrono: high_resolution_clock:

std::chrono::high_resolution_clock::time_point timer_start = std::chrono::high_resolution_clock::now();

// do something

std::chrono::high_resolution_clock::time_point timer_end = std::chrono::high_resolution_clock::now();
double seconds = std::chrono::duration<double>(timer_end - timer_start).count();

Slurm используется в качестве пакетной системы, и я использую эксклюзивную опцию, чтобы убедиться, что на узлах не выполняются другие задания.
Для работы Slurm я использую в основном следующий файл:

 #!/bin/bash
#SBATCH --ntasks 4
#SBATCH --nodes 4
#SBATCH --ntasks-per-node 1
#SBATCH --exclusive
#SBATCH --cpus-per-task 24
export OMP_NUM_THREADS=24
RUNS=10
for ((i=1;i<=RUNS;i++)); do
srun /path/bench_a
done

Для сборки кода я использую CMake и устанавливаю флаги

-O3 -DNDEBUG -march=haswell -DMPICH_IGNORE_CXX_SEEK -std=c++14

Поскольку он одинаков для всех тестов, я не верю, что причина в реализации, а в том, как я строю код или начинаю работу.

Ты хоть представляешь, что мне следует искать, чтобы объяснить это поведение?
Спасибо

3

Решение

Это обычная проблема для бенчмаркинга …
Обычно тесты выполняются 10 000 раз, а затем усредняются. Колебания времени исполнения ниже 10% трудно избежать.

В вашем кластере только 4 узла?
Причиной, которая может объяснить это, является использование сети, особенно если время связи на самом деле составляет довольно большой процент времени выполнения (поскольку вы можете быть не единственным, работающим в то время в кластере). Единственный способ избежать этой проблемы — запустить эталонный тест со всем кластером или в резервировании всего кластера. Вы должны спросить ИТ, что они предпочитают, особенно если у вас есть определенный бюджет в кластере. Но обычно 10 000 прогонов дают довольно хорошую оценку времени выполнения.

(вы правы насчет множественного srun в данном скрипте slurm, всегда запускайте все тесты, которые вы хотите сравнить в одном скрипте :-))

-1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]