2006年10月19日
キャッシュはやはり有効だった
キャッシュにヒットし続けるようにループを分割してみた(簡単のため配列の使い方も少し変えてる).3倍から5倍程度速くなった.あとは sse2 の命令とか使ってみたいところだけどうまく使える形にプログラムを変形できない… むりかなぁ?
初期の単純なネストループ:
for(int p = R; p >0; p--) {
int q = (ISROOT()) ? p-1: 0;
double *u = U+q;
double *v = u++;
register double cv = *v;
for(double const *e = U+Len+p; u != e; u++,v++){
register const double cu = *u;
*v = (1 - MU) * cu + MU * cv;
cv = cu;
}
}
内側のループを分割してキャッシュ上のデータにアクセスしまくる:
double *uu = U;
for(int p = R; p >0; p--) {
int q = (ISROOT()) ? p-1: 0;
double *u = uu+q;
double *v = u++;
register double cv = *v;
for(double const *e = uu+p; u != e; u++,v++){
register const double cu = *u;
*v = (1 - MU) * cu + MU * cv;
cv = cu;
}
}
double const *uue = uu + Len - STEPLEN;
// iteration - STEPLEN * floor(Len/STEPLEN) steps
for(; uu < uue; uu+=STEPLEN) {
for(int p = R; p >0; p--) {
double *u = uu+p-1;
double *v = u++;
register double cv = *v;
for(double const *e = uu+STEPLEN+p; u != e; u++,v++){
register const double cu = *u;
*v = (1 - MU) * cu + MU * cv;
cv = cu;
}
}
}
// last - rest steps
int rlen = Len - STEPLEN * (Len/STEPLEN);
for(int p = R; p >0; p--) {
double *u = uu+p-1;
double *v = u++;
register double cv = *v;
for(double const *e = uu+rlen+p; u != e; u++,v++){
register const double cu = *u;
*v = (1 - MU) * cu + MU * cv;
cv = cu;
}
}
- Comments: 0
- TrackBack (Close): -