CUDA:加载/存储效率与全局内存指令重放之间的关系 我使用的是英伟达视觉剖析器(基于CUDA 5 beta版的Eclipse版本),有一个费米板,有两个性能指标我不懂:

CUDA:加载/存储效率与全局内存指令重放之间的关系 我使用的是英伟达视觉剖析器(基于CUDA 5 beta版的Eclipse版本),有一个费米板,有两个性能指标我不懂:,cuda,Cuda,全局加载/存储效率表示实际内存事务数与请求的事务数之比 全局内存指令重播,表示由于次优内存合并导致的重播而发出的指令的百分比 我的印象是,如果加载/存储效率为100%(即完美合并),则全局内存指令重放应为0,但我见过效率为100%和非零的全局内存指令重放示例。为什么 据我所知,全局加载/存储效率由全局内存访问模式决定,而全局内存指令重放主要由分支发散引起。因此,即使所有内存访问都合并在一起,但存在一些差异,您描述的情况也可能发生 请举例说明次优内存合并访问会导致全局内存指令重放?据我所知,全局

全局加载/存储效率表示实际内存事务数与请求的事务数之比

  • 全局内存指令重播,表示由于次优内存合并导致的重播而发出的指令的百分比

  • 我的印象是,如果加载/存储效率为100%(即完美合并),则全局内存指令重放应为0,但我见过效率为100%和非零的全局内存指令重放示例。为什么


    据我所知,全局加载/存储效率由全局内存访问模式决定,而全局内存指令重放主要由分支发散引起。因此,即使所有内存访问都合并在一起,但存在一些差异,您描述的情况也可能发生


    请举例说明次优内存合并访问会导致全局内存指令重放?

    据我所知,全局加载/存储效率由全局内存访问模式决定,而全局内存指令重放主要由分支发散引起。因此,即使所有内存访问都合并在一起,但存在一些差异,您描述的情况也可能发生


    请举例说明次优内存合并访问导致全局内存指令重放的原因?

    简单的回答是单个warp事务的大小有128 B的限制(我认为是由于总线宽度)。因此,如果warp需要256b的合并数据,那么必须重播第二个128b的指令

    通常,事务只移动32B、64B和128B段中的数据。如果warp事务不符合其中一个,则至少要重播该指令一次。合并模式无法避免这种情况,但它们确实有助于最小化事务。例如,对warp中字节的联合访问可以获得32B事务。在一个warp中合并4B访问(int或float)可以获得单个128B事务

    考虑以下内核:

    __global__ void
    gmemtest(const double* const src, double* const dest, const int size,
             const int eleMoved){
    
      int block_fst = blockIdx.x*blockDim.x*eleMoved;
      size_t thread_fst = block_fst + threadIdx.x*eleMoved;
    
    
      #pragma unroll
      for(size_t i = 0; i < eleMoved; i++){
        if( thread_fst + i < size )
          dest[thread_fst + i] = src[thread_fst + i];
      }
    
    运行
    nvprof--打印gpu跟踪--度量指令重放\u开销
    我们看到:

        ==22053== Profiling result:
        Device         Context  Stream   Kernel           Instruction Replay Overhead
    
       Tesla K20c (0)     1       2    gmemtest(double cons      0.191697
       Tesla K20c (0)     1       2    gmemtest(double cons      0.866548
       Tesla K20c (0)     1       2    gmemtest(double cons      3.472359
       Tesla K20c (0)     1       2    gmemtest(double cons      7.444514
       Tesla K20c (0)     1       2    gmemtest(double cons      0.175090
       Tesla K20c (0)     1       2    gmemtest(double cons      0.912531
       Tesla K20c (0)     1       2    gmemtest(double cons      4.067719
       Tesla K20c (0)     1       2    gmemtest(double cons      7.576686
    
    在实践中,如果您移动的是像warps这样的值为
    double2
    数据的东西,您可能会遇到这种情况


    如果您真的想讨论与性能相关的问题,我推荐这个话题就足够了:

    简单的回答是单个warp事务的大小有128b的限制(我认为是由于总线宽度)。因此,如果warp需要256b的合并数据,那么必须重播第二个128b的指令

    通常,事务只移动32B、64B和128B段中的数据。如果warp事务不符合其中一个,则至少要重播该指令一次。合并模式无法避免这种情况,但它们确实有助于最小化事务。例如,对warp中字节的联合访问可以获得32B事务。在一个warp中合并4B访问(int或float)可以获得单个128B事务

    考虑以下内核:

    __global__ void
    gmemtest(const double* const src, double* const dest, const int size,
             const int eleMoved){
    
      int block_fst = blockIdx.x*blockDim.x*eleMoved;
      size_t thread_fst = block_fst + threadIdx.x*eleMoved;
    
    
      #pragma unroll
      for(size_t i = 0; i < eleMoved; i++){
        if( thread_fst + i < size )
          dest[thread_fst + i] = src[thread_fst + i];
      }
    
    运行
    nvprof--打印gpu跟踪--度量指令重放\u开销
    我们看到:

        ==22053== Profiling result:
        Device         Context  Stream   Kernel           Instruction Replay Overhead
    
       Tesla K20c (0)     1       2    gmemtest(double cons      0.191697
       Tesla K20c (0)     1       2    gmemtest(double cons      0.866548
       Tesla K20c (0)     1       2    gmemtest(double cons      3.472359
       Tesla K20c (0)     1       2    gmemtest(double cons      7.444514
       Tesla K20c (0)     1       2    gmemtest(double cons      0.175090
       Tesla K20c (0)     1       2    gmemtest(double cons      0.912531
       Tesla K20c (0)     1       2    gmemtest(double cons      4.067719
       Tesla K20c (0)     1       2    gmemtest(double cons      7.576686
    
    在实践中,如果您移动的是像warps这样的值为
    double2
    数据的东西,您可能会遇到这种情况

    如果您真的想讨论与性能相关的问题,我非常推荐这篇演讲: