这里主要讲述两种并行计算模式,前缀求和(Prefix Sum)以及卷积(Convolution)。
1. Prefix Sum
前缀求和由一个二元操作符和一个输入向量组成,虽然名字叫求和,但操作符不一定是加法。先解释一下,以加法为例:
第一行是输入,第二行是对应的输出。可以看到,Output[1] = Input[0] + Input[1],而Output[length - 1]就是整个输入向量元素之和。
为什么要使用并行计算?假如用串行计算来计算输出向量,那么向量中越靠后的元素需要等待的时间越长。最后一个元素需要等待0 + 1 + 2 + ... + (n - 2) = (n - 1)(n - 2) / 2次加法计算后,才开始计算该元素。在很多情况下是不容许等待这么长时间的。因此需要并行计算。
一个很简单的想法是为输出向量每一个元素分配一个线程,该线程计算对应元素的值。这个方法有两个明显的问题。首先,这样产生的线程的计算负载非常不均衡,T1只运行一次加法,而T[length - 1]需要运行n - 1次加法。整个并行算法的时间由负载最高的线程决定,也就是O(N)。其次,输入向量中,第一个元素会被所有线程读取,第二个被n - 1个线程读取,总共下来,会有O(N * N)次读取。前面也提到过,内存读取是一种比较慢的操作,过多的内存读取会影响算法的性能。
上面的想法也说明一个现象:并行计算非常的简单,只要不考虑计算的性能。
2. Prefix Sum并行算法一