我只是在我们的power6集群上使用Altivec扩展。我注意到,当我在没有任何优化的情况下编译下面的代码时,我的加速比是4,正如我预期的那样。但是,当我使用-O3标志重新编译它时,我设法获得了60的加速比!
我只是想知道是否有人对此有更多的经验,并且能够提供一些关于编译器如何重新安排我的代码来执行这样的加速的见解。是这里通过汇编和指令流水线进行的唯一可能的优化,还是有其他我遗漏的东西可以包含在我未来的工作中。
int main(void) {
const int m = 1000;
__vector signed int va;
__vector signed int vb;
__vector signed int vc;
__vector signed int vd;
int a[m];
int b[m];
int c[m];
for( int i=0 ; i < m ; i++ ) {
a[i] = i;
b[i] = i;
c[i] = 0;
}
for( int cnt = 0 ; cnt < 10000000 ; cnt++ ) {
vd = (__vector signed int){cnt,cnt,cnt,cnt};
for( int i = 0 ; i < m/4 ; i+=4 ) {
va = vec_ld(0, &a[i]);
vb = vec_ld(0, &b[i]);
vc = vec_add(vd, vec_add(va,vb));
vec_st(vc, 0, &c[i]);
}
}
std::cout << c[0] << ", " << c[1] << ", " << c[2] << ", " << c[3] << "\n";
return 0;
}发布于 2011-09-16 11:20:50
我在Power 7上做了一些事情,我看到了XLC编译器的一些非常奇怪的事情。但不会像这个那么奇怪!(至少不是60倍...)
关于PowerPC系列(至少对于Power6和Power7)需要注意的一件事是,与x86/x64相比,指令延迟非常长,乱序执行非常弱。
因此,内部循环(如您的代码中所写的)将获得极低的IPC。
现在,我能想象得到60倍加速的唯一方法是内部循环在-O3下完全展开的。这是可能的,因为内环的跳闸计数可以被静态地确定为63。
展开内部循环基本上可以填充整个流水线。
当然,我只是在猜测。最好的办法是查看程序集。
另外,你是如何计时的?我在PowerPC上看到的许多奇怪的行为都来自于定时器本身……
编辑:
由于您的示例代码相当简单,因此应该很容易(在程序集中)发现内部循环是否部分或完全展开。
https://stackoverflow.com/questions/7439740
复制相似问题