首先我要说的是,我已经仔细阅读了所有类似的问题:
-
确定每个块的线程和每个网格的块 https://stackoverflow.com/questions/4391162/cuda-determining-threads-per-block-blocks-per-grid
-
每个 SM 的线程数、每个块的线程数 https://stackoverflow.com/questions/17816136/cuda-what-is-the-threads-per-multiprocessor-and-threads-per-block-distinction
-
CUDA 块和线程 https://stackoverflow.com/questions/9342599/cuda-blocks-and-threads
- 扭曲和最佳块数 https://stackoverflow.com/questions/32855684/cuda-warps-and-optimal-number-of-threads-per-block
我的目的是尝试动态计算(而不是硬编码值)我正在开发的前馈神经网络库。
My data is not与我见过的大多数例子一样,它是一个方格(矩阵),它是两个向量生成一个矩阵,行与列不相等:
float x[6] {1.f, 1.f, 0.f, 1.f, 1.f, 0.f};
thrust::device_vector<float> in_vec( x, x+6 );
float y[9] {1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f};
thrust::device_vector<float> w_vec( y, y+9 );
thrust::device_vector<float> o_wec(9);
thrust::device_vector<float> mtx_vec( 9 * 6 );
float * i_ptr = thrust::raw_pointer_cast( in_vec.data() );
float * w_ptr = thrust::raw_pointer_cast( w_vec.data() );
float * out_ptr = thrust::raw_pointer_cast( mtx_vec.data() );
dim3 threadsPerBlock(9,6);
dim3 numBlocks(1,1);
prop_mtx<<<numBlocks,threadsPerBlock>>>( w_ptr, i_ptr, out_ptr, 6 );
和内核:
__global__ void prop_mtx( float * w, float * i, float * o, int s )
{
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
o[y + x * s] = w[x] * i[y];
}
我采用这种方法的原因是,当涉及到向量/矩阵计算时,它在 ANN 计算中有意义。
我想保持这一点的一致性,并且据我所知,使用 2D 网格进行权重 * 输入计算是合理的。
我必须将每个块的线程计算为二维,并且网格中的线程数量不等。
我使用的是 GTX 660,它具有:
CUDA Capability Major/Minor version number: 3.0
Total amount of global memory: 2047 MBytes
( 5) Multiprocessors, (192) CUDA Cores/MP: 960 CUDA Cores
Maximum Texture Dimension Size (x,y,z) 1D=(65536), 2D=(65536, 65536), 3D=(4096, 4096, 4096)
Warp size: 32
Maximum number of threads per multiprocessor: 2048
Maximum number of threads per block: 1024
Max dimension size of a thread block (x,y,z): (1024, 1024, 64)
Max dimension size of a grid size (x,y,z): (2147483647, 65535, 65535)
我试图了解如何推断/计算网格大小、每个块的线程以及块的数量。
假设我有一个包含 800 个项目的权重向量和一个包含 6500 个项目的输入向量。
- 这是否意味着我真正需要的是 800,6500 的 2D 网格?据我了解,还有什么会提供不正确的结果吗?
我知道每个块的最大线程数是 1024,但因为它是 2D 网格,所以更有可能是:
dim3 threadPerBlock(X,Y);
由于我的网格不是方阵,我需要以不同的方式计算每个块的X,Y线程?
或者我需要先推断出所需的块数?
最后,由于我的经纱尺寸是 32,
-
无论所有其他参数如何,是否最小网格尺寸需要至少为 32,或 32 的倍数?我需要at least每个块 32 个线程,或者最小数量为 32 的网格大小?
任何伪代码或我应该如何解决这个问题的解释都将不胜感激。
我尝试过的是将数据除以 32 环绕大小来计算 2D 网格大小。
然后我考虑使用可用的 SM 来计算网格线程。例如
800 weights / 5 SM, = 160 x's per SM
6500 inputs / 5 SM, = 1300 y's per SM
但我不知道从那时起该做什么。
最后,我考虑先求输入权重比:
6500/800 = 8.125
这意味着 X 使用 32 个最小网格大小,
Y 必须乘以 8.125 * 32
因此,我的threadsPerBlock 将是:
dim3 threadsPerBlock(32,260);
那当然是每块8320个线程,远远超过每块1024个。
所以这是我的问题:如何不超过每块 1024 个线程,同时保留数据的正确网格大小?
PS:我的问题不是关于优化代码,而是了解如何在设备上分发线程和网格数据。