【发布时间】:2017-02-26 08:19:33
【问题描述】:
早安。
我开始学习 cuda 编程,我正在学习性能。我在 CUDA 网站上读到,为了获得良好的性能,我们应该考虑四件事:
-warps per SM(系统多处理器) - 每个 SM 块 - 注册每个 SM - 每个 SM 共享内存
所以我首先要回顾一下,根据 GPU,我根据每个 SM 的最大扭曲和每个 SM 的块来定义内核的尺寸。我的任务是执行一亿次求和来衡量哪种方法更好。
我所做的是一个 for 循环,在该循环中,我在每次迭代时启动一个内核以最大化占用率。例如,对于 NVidia 1080 GPU,我读到:
int max_blocks = 32; //maximum number of active blocks per SM
int max_threads_per_Block = 64; //maximum number of active threads per SM
int max_threads = 2048;
这为每个 SM 提供了总共 2048 个线程,并保证了最大占用率。这个 GPU 可以有 64 个活动 warp,每个有 32 个线程。在这个 GPU 中,一个活动块有 2 个扭曲,这意味着每个块可以同时拥有 64 个活动线程。有了这个我启动内核如下:
dim3 threadsPerBlock(max_threads_per_Block);
dim3 numBlocks(max_blocks);
VecAdd<<<numBlocks, threadsPerBlock>>>(d_A, d_B, d_C,max_threads);
令我惊讶的是,如果我像这样直接启动这个内核:
int N = total_ops; //in this case one thousand millions
dim3 threadsPerBlock(256);
dim3 numBlocks(2*N / threadsPerBlock.x);
VecAdd<<<numBlocks, threadsPerBlock>>>(d_A, d_B, d_C,);
性能更好(消耗时间)。我在相同的执行中启动了 5 次相同的实验以避免异常值。我的问题是:有没有办法管理占用以获得比编译器和运行时 API 更好的结果?我知道我尝试做的优化已经以某种方式由 GPU 管理。我知道,如果有一个文档解释了我们应该如何启动软件(上面的链接)以实现良好的性能,它应该是一种控制它的方法。
谢谢
【问题讨论】:
标签: c++ performance cuda gpu nvidia