4.1Reduction模型

本文深入探讨了Reduction模型,一种广泛应用于并行计算领域的计算模型。文章解释了Reduction的基本概念,包括其满足的联合性和交换性原则,以及常见的算符如Max、Min、Sum和Product。此外,还详细分析了Reduction树的性能考虑,提出了优化计算顺序以提高效率的方法,并提供了代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Reduction

Reduction是一种广泛使用的计算模型,特别是在并行计算领域。简单地来说,Reduction就是一系列的划分(Partition)和汇总(Summarize)操作的集合:对输入数据分块,对每一个分块汇总,然后再将汇总后的数据视为新的输入数据,重复分块和汇总,直到得到最终结果,可以想象为一个倒置的树。Google和Hadoop的Map/Reduce中的Reduce计算就是一个很好的例子。

Reduction模型满足联合性和交换性:联合性:(a + b) + c = a + (b + c),交换性:a + b = b + c。换言之,Reduction模型对输入数据的顺序没有特定的要求。模型满足这两个性质,则里面的算符也必须满足这两个性质。常见的Reduction算符,也可以说是Reduction操作,包括了Max,Min,Sum,Product等,用户也可以自定义算符,但一定要注意,自定义的算符首先需要满足上述两个性质,其次需要定义单位值(Identity Value)。单位值是指一种特殊的值,它的存在对计算结果没有影响,比如,对Sum计算,0就是单位值。单位值常常被用来填充数据,使得数据长度为2的幂方值或某一特定值的整数倍。

一个Max算符的Reduction树如下图所示:

 

2. Reduction树的性能考虑

这里以一个求向量元素之和的计算任务为例来说明如何提高Reduction模型的性能。

向量求和可以如下图表示:

显而易见,这个过程包含了O(llogN)步,一共有O(N)的算符操作,每一步都会让活动的线程数减半。

现在来考虑性能。假设一个Warp大小为2个Thread(仅仅是假设,大多数情况下Warp大小为32T),那么一共需要2个Warp。在STEP1时,所有的4个Thread都处于活动状态,而到了STEP2,就只有T0和T2处于活动状态。但是,前面有提到过,Warp是调度的最小单位,所以,只要在Warp中有任何的活动线程,整个Warp就处于活动状态,其中的非活动状态的线程仍然会占用计算资源。因此,在STEP2时,尽管只有2个活动线程,但是仍然会占用4个线程的计算开销。

通过改变Reduction树计算方式可以解决这个问题。注意到上面的计算中,随着计算步骤增加,待计算的两个数据之间的距离是增加的。比如STEP1中3+1=4,3和1间距离为1,而STEP2中4+7=11,4和7间的距离为2。活动线程间的距离是数据距离的2倍,在它们之间是非活动线程。这样在计算中间过程中总有活动线程被非活动线程所分隔,就总会有多余1个的Warp同时包含了活动和非活动线程。

现在将上面的计算步骤反过来,先从距离为4的数据开始计算,即STEP1中T0会计算3+4=7而不是3+1=4。可以验证,这样的计算步骤所有的活动线程都集中在前部,所有的非活动线程都在后部。因此,至多只会有1个Warp同时包含了活动和非活动线程。

从上述例子可以看出,尽管Reduction模型对数据顺序没有要求,不同的计算顺序对性能是有影响的。

3. 代码示例

// just the kernel function

void sumOfVec(float *input) {

    // take advantage of shared memory to speed up calculation

    // each thread take 2 elements from input to shared memory

    __shared__ float partialSum[2 * BLOCK_SIZE]
    int t = threadIdx.x;
    int start = 2 * blockIdx.x * blockDim.x;
    partialSum[t] = input[start + t];
    partialSum[t + blockDim.x] = input[start + t + blockDim.x];

    // reduction begin
    for (int i = blockDim.x; i > 0; i /= 2) {
        __syncthreads();
        if (t < i) {
            partialSum[t] = partialSum[t + i];
        }
    }
}            

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值