« 上一篇下一篇 »

多指令发送处理器

我们可以使用仿射循环转换来优化指令发送计算机性能一个软件流水线化循环的性能受到两个因素的限制:先后关系约束中的环,以及对关键资源的使用。通过改变最内层循环的组成,我们可以改进这些限制。

首先,我们可以使用循环转换来创立最内层的可并行化循环,从而完全消除先后关系约束中的环。假设一个程序有两个循环,其中的外层循环是可并行化的,而内层循环不可并行化。我们可以交换这两个循环,使得内层循环变成可并行化的,从而创造出更多的指令级并行化机会。请注意,我们并不要求最内层循环的迭代之间一定是完全可并行化的。只要其依赖关系所确定的环短到可以充分利用硬件资源就足够了。

我们也可以通过改进一个循环中资源使用的平衡性来放松因资源使用而引起的限制。假设一个循环只使用加法器,而另一个只使用乘法器。假设一个循环因为内存而受到制约,另一个循环因为计算量而受到制约。比较好的做法是把这些例子中的循环对融合到一起,以便同时充分利用所有的功能单元。

向量和SIMD指令

除了多指令问题之外,还有其他两种重要的指令级并行性:向量和S1MD运算。在这两种情况下,发送一个指令可以对一个数据向量的所有元素进行相同运算。

前面提到过,很多早期的超级计算机使用了向量指令。向量运算以流水线化的方式执行,该向量的元素被串行获取,对不同元素的计算相互重叠。在先进的向量计算机中,向量运算可以链接起来:当生成结果向量的元素时,它们立刻被另一个向量指令的运算消耗掉,不需要等待所有的结果都计算完成。不仅如此,在具有散播/收集(scatter/gather)硬件的先进计算机中,向量的元素不要求是连续的,可以用一个下标向量确定这些元素该放在哪里。

SIMD指令指定了对连续内存位置执行的相同运算。这些指令从内存中并行加载数据,把它们存放在宽寄存器中,并使用并行硬件来计算它们。很多媒体、图形和数字信号处理应用可以利用这些运算。低端媒体处理器只需要一次发射一个SIMD指令就可以获得指令级并行性。高端处理器可以把SIMD和多指令发射结合起来以获取更好的性能。

SIMD及向量指令生成和数据局部性优化之间具有很多相似性。当我们找到在连续内存位置上运算的独立分划单元时,就对这些迭代进行条状挖掘,并把最内层循环中的运算交织起来。

生成SIMD指令有两个难点。首先,有些机器要求从内存中获取的SIMD数据是位对齐的。比如,它们可能要求将256字节的SIMD运算分量放在为256的倍数的地址上。如果源循环只在一个数据数组上运算,我们可以生成一个主循环来处理对齐的数据,而这个循环的前面和后面都有附加的代码来计算边界上的元素。但是对于在多个数组上运算的循环,就有可能无法同时对齐所有的数据。第二,一个循环的连续迭代所使用的数据可能不是连续的。这种例子包括很多重要的数字信号处理的算法,比如Viterbi解码器和快速傅里叶变换。要利用SIMD指令的话,有可能需要一些额外的用于移动数据的指令。

« 上一篇下一篇 »