c++ - 如何使并行 cudaMalloc 快速?
问题描述
在 4 个不同的NVIDIA V100 GPU上分配大量内存时,我观察到有关通过 OpenMP 进行并行化的以下行为:
使用该#pragma omp parallel for
指令并因此cudaMalloc
在每个 GPU 上并行调用,其性能与完全串行调用相同。这在两个 HPC 系统上进行了测试并验证了相同的效果:IBM Power AC922和AWS 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
- 我也尝试
std::thread
用相同的结果代替 OpenMP。
解决方案
推荐阅读
- javascript - 获得10分后需要重新加载页面
- mysql - mysql group by uid 计算连续日期差异
- html - 项目符号点未能在中心对齐
- arrays - C:当矩阵维数为奇数时,以矩阵为参数的函数打印错误
- python - 在 Python 中计算图像的 fft2
- java - 如何使用 java 函数接口实现生成完美数字的函数?
- arp - 为什么“arp -a”显示不一致的输出差异很大?
- javascript - 如何将 Google recaptcha v2 注入网页?
- firebase - Flutter:FieldValue.delete() 只能出现在你更新数据的顶层
- ios - 从 Web 服务器发送 SMS 消息