【问题标题】:How to partition static data into multiple GPUs?如何将静态数据划分为多个 GPU?
【发布时间】:2012-12-18 19:35:29
【问题描述】:

我想对一个大型数据集进行分区并将工作拆分到多个 GPU 上。我想让这些数据静态化,这样我就不必在第二次运行时加载到 GPU。现在的问题是,pthread_create 要求将所有输入数据组装成一个“结构”,我不确定将一堆静态数据组装成一个结构是否可行。感谢您的任何建议。

【问题讨论】:

  • pthread_create 和 CUDA 有什么关系?
  • 我希望有另一种选择,但 Sanders 的“CUDA 示例”通过使用 pthread_create 为非默认 GPU 创建新线程演示了一个多 GPU 示例。
  • 要使用非默认GPU,我们必须创建一个新线程,对吧?或者干脆调用运行时“cudaSetDevice”就可以了?
  • 自 CUDA 4 发布以来,您无需为多个 GPU 使用单独的主机线程。你需要看看this GTC presentation
  • 很棒的资源!快速浏览一下 powerpoint 告诉我“cudaSetDevice”将使多个 GPU 异步运行,但稍后会研究它!

标签: cuda pthreads gpu


【解决方案1】:

在“现代”CUDA 多 GPU 中,不再需要使用不同的主机线程来保存给定设备上的上下文。从 CUDA 4.0 开始,API 是线程安全的,一个主机线程可以简单地使用 cudaSetDevice 来保存和处理多个上下文。

关于如何在 CUDA 4.x 或 CUDA 5 中将大型数据集分布到多个 GPU 上的一个非常非常基本的示例,可以很简单:

int remainder = N;
int* plens = new int[ngpus];
float** pvals = new float*[ngpus];
float* source = &host_array[0];
for(int i=0; i<ngpus; i++) {
    const int blen = N/gpus;
    plens[i] = blen;
    remainder -= blen;
    if (remainder < blen) {
        plens[i] += remaninder;
        remainder = 0;
    }
    size_t sz = sizeof(float) * size_t(plens[i]);
    cudaSetDevice(i);
    cudaMalloc((void **)&pvals[i], sz);
    cudaMemcpy(pvals[i], source, sz, cudaMemcpyHostToDevice);
    source += plens[i];
}

[免责声明:用浏览器编写,从未编译或测试过,风险自负]

假设 GPU 从 [0,ngpus-1] 开始按顺序编号,并且源数据保存在长度为 N 的浮点数组 host_array 中。你在pvals 中得到一个设备指针数组,在plens 中得到每个数组的长度。请注意,每个指针仅在分配它的上下文中有效,因此请确保在将指针用于内核启动或 API 调用之前选择设备。

【讨论】:

  • 嗨 talonmies,我们如何联系您?
  • 优秀。我只是以为您对大规模真实 GPU 应用程序感兴趣
  • @flow:确实我对这些东西很感兴趣。但我没有兴趣被与我没有专业或个人关系的完全陌生的陌生人主动联系轰炸,如果我在像这样的开放论坛上提供我的联系方式,就会发生这种情况。
  • 我完全理解你的情况。如果您有兴趣投稿,请发送电子邮件至 werner.schroedinger@googlemail.com
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-23
  • 2020-05-23
  • 1970-01-01
  • 1970-01-01
  • 2017-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多