我目前正在做家庭作业,我必须实现几个矩阵乘法内核,尝试几个网格和块尺寸并对结果进行基准测试。
我的第一个内核使用1D线程块(其中每个线程块负责计算一个1×n子矩阵,每个线程负责该子矩阵内的一个元素),我的第二个内核是2D块(其中每个线程块负责计算一个方形子矩阵,每个线程负责该子矩阵内的一个元素。他们俩都在使用全局记忆。
我使用大小为4096 * 4096的矩阵启动了几个测试,其中每个块的线程范围从64到1024(1D内核),以及8 * 8到32 * 32(2D内核)。我希望两个内核都能获得相同的性能,但不知何故2D内核似乎总是稍微快一点。
这可以通过以下事实来解释:使用2D线程块,在同一区域中会发生更多的内存访问"这会利用某种缓存机制吗?
答案 0 :(得分:-1)
是的,使用2D块减少了每个块访问的不同矩阵元素的数量。这个简单的计算应该清楚说明:
Calculation of A*B=C
Matrix size: 4096*4096
Block size: 1024x1
Number of different elements read from Matrix A: 1 row = 4096 elements
Number of different elements read from Matrix B: 1024 columnes = 4096*1024
Sum: 4193280
Block size: 32x32
Number of different elements read from Matrix A: 32 rows = 32*1024
Number of different elements read from Matrix B: 32 columnes = 32*1024
Sum: 65536
要在结果矩阵中计算C(i,j),您必须从矩阵A中读取第i行,从矩阵B中读取第j列。
因此,如果要计算结果矩阵的第一行,则必须读取第一行的N倍(假设矩阵为NxN),并且每列在矩阵B中读取一次。
4x1 Block
v v v v
>0 1 2 3 0 1 2 3 x x x x
4 5 6 7 4 5 6 7 - - - -
8 9 A B 8 9 A B - - - -
C D E F C D E F - - - -
2x2 Block
v v
>0 1 2 3 0 1 2 3 x x - -
>4 5 6 7 4 5 6 7 x x - -
8 9 A B 8 9 A B - - - -
C D E F C D E F - - - -
箭头指向计算x
指示的元素所需的行和列。