首页 > 解决方案 > 如何使并行 cudaMalloc 快速?

问题描述

在 4 个不同的NVIDIA V100 GPU上分配大量内存时,我观察到有关通过 OpenMP 进行并行化的以下行为:

使用该#pragma omp parallel for指令并因此cudaMalloc在每个 GPU 上并行调用,其性能与完全串行调用相同。这在两个 HPC 系统上进行了测试并验证了相同的效果:IBM Power AC922AWS EC2 p3dn.24xlarge。(这些数字是在 Power 机器上获得的。)

./test 4000000000

# serial

GPU 0: 0.472018550
GPU 1: 0.325776811
GPU 2: 0.334342752
GPU 3: 0.337432169
total: 1.469773541

# parallel

GPU 0: 1.199741600
GPU 2: 1.200597044
GPU 3: 1.200619017
GPU 1: 1.482700315
total: 1.493352924

如何使并行化更快?

这是我的代码:

#include <chrono>
#include <iomanip>
#include <iostream>

int main(int argc, char* argv[]) {
  size_t num_elements = std::stoull(argv[1]);
  
  auto t0s = std::chrono::high_resolution_clock::now();
  #pragma omp parallel for
  for (int i = 0; i < 4; ++i)
  {
    auto t0is = std::chrono::high_resolution_clock::now();

    cudaSetDevice(i);
    int* ptr;
    cudaMalloc((void**)&ptr, sizeof(int) * num_elements);

    auto t1is = std::chrono::high_resolution_clock::now();
    std::cout << "GPU " << i << ": " << std::fixed << std::setprecision(9)
            << std::chrono::duration<double>(t1is - t0is).count() << std::endl;
  }

  auto t1s = std::chrono::high_resolution_clock::now();
  std::cout << "total: " << std::fixed << std::setprecision(9)
            << std::chrono::duration<double>(t1s - t0s).count() << std::endl;

  return 0;
}

您可以使用以下命令编译微基准:

nvcc -std=c++11 -Xcompiler -fopenmp -O3 test.cu -o test

标签: c++cudaopenmp

解决方案


推荐阅读