在内核块执行之间,GPU多处理器的共享内存会如何处理?

刺柏

假设我有一个带有一堆块的CUDA内核,并且假定在同一对称多处理器(即,所有扭曲的共享内存区域相同的单元)上的另一个块之后紧接着安排了一个块。NVIDIA目前未在API或每个GPU文档中指定两次执行之间共享内存发生了什么。但是,实际上,关于块的共享内存内容,以下哪项成立?

  • 最后一个预定的块处于相同的状态。
  • 它是空白。
  • 它包含不可预见的垃圾。

为了缩小可能出现的情况的变化范围,请具体参考以下情况:每个块使用最大可能的共享内存-Kepler GPU上为48 KB。

罗杰·达尔

NVIDIA不在此级别上发布硬件的行为,因此您应将其视为未定义(如@datenwolf所说)。但是,当然,给定块看到的共享内存的内容不会是随机的。硬件没有必要花费时间清除内存。

GPU可以在每个SM上同时运行许多块。给定内核同时运行的块数取决于各种因素。因此,例如,如果共享内存是限制因素,则每个SM将运行与共享内存中一样多的块。因此,如果共享内存为48K,而一个块需要10K,则可以同时使用40K运行4个块。因此,如果您的设备具有8个SM,我的猜测是给定块的共享内存将有32个(4 * 8)可能的固定位置。因此,当计划了一个新块时,会将其分配给这些位置之一,并查看该位置中运行的前一个块留下的共享内存。

该API无法为块提供检测其在哪个位置运行的方法。块的调度是动态确定的,可能很难预测。

如果使用GPU进行显示,则它可能正在同时运行其他内核(着色器),可能以怪异而奇妙的方式覆盖CUDA内核中各块之间的共享内存。甚至CUDA都可能在幕后运行其他内核。

编辑:

我写了一个小程序来测试事情(包括在下面)。该程序将一个块应存储在共享内存中的整数数作为参数。然后,它启动100,000个块,每个块有一个线程。每个块检查其共享内存是否已初始化。如果已初始化,则该块将不执行任何其他操作。如果未初始化,则该块将初始化内存并增加全局计数。初始化模式是一个递增的数字序列,以避免出现部分重叠的初始化共享内存缓冲区有效的情况。

在GTX660(Kepler,CC 3.0,5个SM)上,配置了48K共享内存,CC 3.0 Release build,我得到以下结果:

C:\rd\projects\cpp\test_cuda\Release>test_cuda.exe 10000
Shared memory initializations: 5

我运行了几次,每次都得到相同的结果。这与我最初所做的猜测相符,因为10000个整数占用〜40K,因此每个SM将有一个并发块的空间,并且该设备具有5个SM。

但是,当我将共享内存减少到2500个整数(〜10K)时,期望获得20个初始化,并运行几次,结果得到了不同的高数字:

Shared memory initializations: 32,822
Shared memory initializations: 99,996
Shared memory initializations: 35,281
Shared memory initializations: 30,748

因此,在这种情况下,我对固定位置的猜测完全无效。

然后,我尝试将共享内存减少到100个整数(在48K中将有122个块的空间),并且始终得到:

Shared memory initializations: 480

因此,同样,不是预期的数目,而且令人惊讶的是,即使每个块使用的共享内存量较小,可能的变化也明显更少。

看起来,如果您决心将自己射击,可以使用一个大的共享内存块来保持一致:)此外,它是在GPU上运行的,该GPU也用于显示Windows 7 with Aero(A GPU加速主题),并且渲染似乎不会受到干扰,因为在内核运行时桌面冻结了。

程序:

#include "cuda_runtime.h"

#include <iostream>
#include <sstream>
using namespace std;

#define assertCudaSuccess(ans) { _assertCudaSuccess((ans), __FILE__, __LINE__); }
inline void _assertCudaSuccess(cudaError_t code, char *file, int line)
{
  if (code != cudaSuccess) {
    fprintf(stderr,"CUDA Error: %s %s %d\n", cudaGetErrorString(code), file, line);
    exit(code);
  }
}

__global__ void shared_memory_persistence_test(int n_shared_ints);
__device__ int init_cnt_d(0);

int main(int argc, char* argv[])
{
  cout.imbue(locale(""));
  int n_shared_ints;
  stringstream(string(argv[1])) >> n_shared_ints;
  shared_memory_persistence_test<<<dim3(100, 1000), 1, n_shared_ints * sizeof(int)>>>(n_shared_ints);
  assertCudaSuccess(cudaPeekAtLastError());
  assertCudaSuccess(cudaDeviceSynchronize());
  int init_cnt_h;
  assertCudaSuccess(cudaMemcpyFromSymbol(&init_cnt_h, init_cnt_d, sizeof(int), 0, cudaMemcpyDeviceToHost));
  cout << "Shared memory initializations: " << init_cnt_h << endl;
  return 0;
}

__global__ void shared_memory_persistence_test(int n_shared_ints)
{
  extern __shared__ int shared[];

  for (int i(0); i < n_shared_ints; ++i) {
    if (shared[i] != i) {
      for (int i(0); i < n_shared_ints; ++i) {
        shared[i] = i;
      }
      atomicAdd(&init_cnt_d, 1);
      break;
    }
  }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在内核块执行之间,GPU多处理器的共享内存会怎样?

来自分类Dev

Cuda优化,多处理器,并发内核执行

来自分类Dev

Perl ithreads:共享变量-多处理器内核线程-可见性

来自分类Dev

在CUDA统一内存多GPU或多处理器中使用原子算术运算

来自分类Dev

处理器与内核(多处理器与多核)的定义

来自分类Dev

对“ xz”的多处理器支持?

来自分类Dev

多处理器调度

来自分类Dev

多处理器和多处理系统之间有什么区别?

来自分类Dev

在Linux(CentOS)/多处理器设置中,如何将CPU内核分配给NUMA节点?

来自分类Dev

在Linux(CentOS)/多处理器设置中,如何将CPU内核分配给NUMA节点?

来自分类Dev

分配给多处理器的活动块集的行为是什么?

来自分类Dev

CUDA | 对多处理器数量的兴趣-与SM混淆

来自分类Dev

寻找多处理器DAG的静态调度-库?

来自分类Dev

多处理器架构和Ring 3

来自分类Dev

如何在许多处理器上运行boost :: threads?

来自分类Dev

C ++如何限制Visual Studio多处理器编译

来自分类Dev

如何在许多处理器上运行boost :: threads?

来自分类Dev

如何为许多处理器体系结构引用.dll?

来自分类Dev

如何在Visual Studio中启用多处理器构建

来自分类Dev

test_and_set() 指令如何在多处理器上仍然有效?

来自分类Dev

多线程应用程序如何在多处理器系统中工作

来自分类Dev

流多处理器,CUDA中每个流处理器的核心

来自分类Dev

Chapel编译器是否可以进行多处理器编译?

来自分类Dev

内核与处理器之间的差异

来自分类Dev

std :: call_once多处理器安全吗?

来自分类Dev

python中需要与多处理器进行同步吗?

来自分类Dev

以编程方式检索每个多处理器的最大块数

来自分类Dev

SQL Oracle-多处理器调度:贪心数分区

来自分类Dev

最新更新之后,Ubuntu 14.04使用过多处理器

Related 相关文章

  1. 1

    在内核块执行之间,GPU多处理器的共享内存会怎样?

  2. 2

    Cuda优化,多处理器,并发内核执行

  3. 3

    Perl ithreads:共享变量-多处理器内核线程-可见性

  4. 4

    在CUDA统一内存多GPU或多处理器中使用原子算术运算

  5. 5

    处理器与内核(多处理器与多核)的定义

  6. 6

    对“ xz”的多处理器支持?

  7. 7

    多处理器调度

  8. 8

    多处理器和多处理系统之间有什么区别?

  9. 9

    在Linux(CentOS)/多处理器设置中,如何将CPU内核分配给NUMA节点?

  10. 10

    在Linux(CentOS)/多处理器设置中,如何将CPU内核分配给NUMA节点?

  11. 11

    分配给多处理器的活动块集的行为是什么?

  12. 12

    CUDA | 对多处理器数量的兴趣-与SM混淆

  13. 13

    寻找多处理器DAG的静态调度-库?

  14. 14

    多处理器架构和Ring 3

  15. 15

    如何在许多处理器上运行boost :: threads?

  16. 16

    C ++如何限制Visual Studio多处理器编译

  17. 17

    如何在许多处理器上运行boost :: threads?

  18. 18

    如何为许多处理器体系结构引用.dll?

  19. 19

    如何在Visual Studio中启用多处理器构建

  20. 20

    test_and_set() 指令如何在多处理器上仍然有效?

  21. 21

    多线程应用程序如何在多处理器系统中工作

  22. 22

    流多处理器,CUDA中每个流处理器的核心

  23. 23

    Chapel编译器是否可以进行多处理器编译?

  24. 24

    内核与处理器之间的差异

  25. 25

    std :: call_once多处理器安全吗?

  26. 26

    python中需要与多处理器进行同步吗?

  27. 27

    以编程方式检索每个多处理器的最大块数

  28. 28

    SQL Oracle-多处理器调度:贪心数分区

  29. 29

    最新更新之后,Ubuntu 14.04使用过多处理器

热门标签

归档