首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >128位矢量与Cuda相加,性能问题

128位矢量与Cuda相加,性能问题
EN

Stack Overflow用户
提问于 2013-12-16 14:58:02
回答 1查看 564关注 0票数 0

我想用进位增加128位向量。我的128位版本(下面代码中的addKernel128)比基本的32位版本(下面的addKernel32)慢两倍。我有记忆合并问题吗?我怎样才能获得更好的表现?

代码语言:javascript
复制
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <iostream>

#define UADDO(c, a, b) asm volatile("add.cc.u32 %0, %1, %2;" : "=r"(c) : "r"(a) , "r"(b));
#define UADDC(c, a, b) asm volatile("addc.cc.u32 %0, %1, %2;" : "=r"(c) : "r"(a) , "r"(b));

__global__ void addKernel32(unsigned int *c, const unsigned int *a, const unsigned int *b, const int size)
{
  int tid = blockIdx.x * blockDim.x + threadIdx.x;

  while (tid < size)
  {
    c[tid] = a[tid] + b[tid];
    tid += blockDim.x * gridDim.x;
  }
}

__global__ void addKernel128(unsigned *c, const unsigned *a, const unsigned *b, const int size)
{
  int tid = blockIdx.x * blockDim.x + threadIdx.x;

  while (tid < size / 4)
  {
    uint4 a4 = ((const uint4 *)a)[tid],
          b4 = ((const uint4 *)b)[tid],
          c4;

    UADDO(c4.x, a4.x, b4.x)
    UADDC(c4.y, a4.y, b4.y) // add with carry
    UADDC(c4.z, a4.z, b4.z) // add with carry
    UADDC(c4.w, a4.w, b4.w) // add with carry (no overflow checking for clarity)

    ((uint4 *)c)[tid] = c4;

    tid += blockDim.x * gridDim.x;
  }
}

int main()
{
  const int size = 10000000; // 10 million

  unsigned int *d_a, *d_b, *d_c;

  cudaMalloc((void**)&d_a, size * sizeof(int));
  cudaMalloc((void**)&d_b, size * sizeof(int));
  cudaMalloc((void**)&d_c, size * sizeof(int));

  cudaMemset(d_a, 1, size * sizeof(int)); // dummy init just for the example
  cudaMemset(d_b, 2, size * sizeof(int)); // dummy init just for the example
  cudaMemset(d_c, 0, size * sizeof(int));

  int nbThreads = 512;
  int nbBlocks = 1024; // for example

  cudaEvent_t start, stop;
  cudaEventCreate(&start);
  cudaEventCreate(&stop);
  cudaEventRecord(start);

  addKernel128<<<nbBlocks, nbThreads>>>(d_c, d_a, d_b, size);

  cudaEventRecord(stop);
  cudaEventSynchronize(stop);
  float m = 0;
  cudaEventElapsedTime(&m, start, stop);

  cudaFree(d_c);
  cudaFree(d_b);
  cudaFree(d_a);
  cudaDeviceReset();
  printf("Elapsed = %g\n", m);
  return 0;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-16 16:21:03

由于各种原因,在WDDM GPU上编写CUDA代码是相当困难的。其中大部分都围绕着这样一个事实: GPU是由Windows作为显示设备管理的,这可以在计时过程中引入各种各样的工件。一个例子是windows驱动程序和WDDM将批处理GPU的工作,并且可能在CUDA GPU工作的中间交叉显示工作。

  • 如果可能的话,在linux上计时您的cuda代码,或者在TCC模式下在windows GPU上计时。
  • 为了提高性能,请始终在没有-G开关的情况下进行构建。在visual studio中,这通常对应于构建发行版,而不是项目的调试版本。
  • 为了获得一个良好的性能比较,通常建议在实际测量计时结果之前进行一些“热身运行”。这些都会消除“创业”等一次性测量问题,你是否更有可能得到合理的结果。您还可能希望多次运行代码并对结果进行平均值。
  • 通常,使用与GPU相对应的arch标志进行编译也是可取的,例如用于CC2.0GPU的-arch=sm_20
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20613895

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档