程式碼最佳化試驗——短迴圈最佳化(上) (轉)

gugu99發表於2007-08-15
程式碼最佳化試驗——短迴圈最佳化(上) (轉)[@more@]

上次比較佇列效能,SGI-STL比我的高了一倍還多(是我的2.3倍,還是夾雜在一堆別的程式碼中的,估計實際上3倍都擋不住),於是下決心改善程式碼質量。但這需要不斷的積累,現在只能一點點的來——哎,什麼時候才能看見大師的背影呢。就從短迴圈開始吧,這個對cpu的開銷是非常大的,而程式中出現的機率比較大,因此,對其的最佳化,能帶來效率的大幅提升。為了說明問題,做了如下的測試:(我把我寫的Timer.h拷到Inlcude目錄裡了)測試環境:C500、192RAM、win2000Sp3、關掉其他前臺程式

測試程式1

#include

#include

XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />

void sum1()

{

int j = 0;

for (unsigned i = 1; i < 630001; i++) j += i;

}

void sum2()

{

int j = 0;

for (unsigned i = 1; i < 630001;)

{

j += i++;

j += i++;

}

}

void sum3()

{

int j = 0;

for (unsigned i = 1; i < 630001;)

{

j += i++;

j += i++;

j += i++;

}

}

void sum4()

{

int j = 0;

for (unsigned i = 1; i < 630001;)

{

j += i++;

j += i++;

j += i++;

j += i++;

}

}

void sum5()

{

int j = 0;

for (unsigned i = 1; i < 630001;)

{

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

}

}

void sum6()

{

int j = 0;

for (unsigned i = 1; i < 630001;)

{

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

}

}

void sum7()

{

int j = 0;

for (unsigned i = 1; i < 630001;)

{

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

}

}

void sum8()

{

int j = 0;

for (unsigned i = 1; i < 630001;)

{

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

}

}

void sum9()

{

int j = 0;

for (unsigned i = 1; i < 630001;)

{

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

}

}

void sum10()

{

int j = 0;

for (unsigned i = 1; i < 630001;)

{

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

j += i++;

}

}

int main()

{

Timer timer; double t;

for (unsigned k = 0; k < 3; k++)

{

timer.Start();

sum1();

t = timer.GetTime();

cout <

timer.Start();

sum2();

t = timer.GetTime();

cout <

timer.Start();

sum3();

t = timer.GetTime();

cout <

timer.Start();

sum4();

t = timer.GetTime();

cout <

timer.Start();

sum5();

t = timer.GetTime();

cout <

timer.Start();

sum6();

t = timer.GetTime();

cout <

timer.Start();

sum7();

t = timer.GetTime();

cout <

timer.Start();

sum8();

t = timer.GetTime();

cout <

timer.Start();

sum9();

t = timer.GetTime();

cout <

timer.Start();

sum10();

t = timer.GetTime();

cout <

}

return 0;

}

測試結果1

Sum1

Sum2

Sum3

Sum4

Sum5

Sum6

Sum7

Sum8

Sum9

Sum10

VC6 Release版本,生成檔案大小57,344B,以下時間單位ms

3.83457

2.59251

1.936

1.68038

1.51304

1.81448

1.71642

1.71418

1.44795

1.49488

3.82311

2.51848

1.93628

1.71474

1.51276

1.75022

1.7167

1.77564

1.44711

1.42728

3.82479

2.51848

1.93544

1.7315

1.51304

1.74994

1.7167

1.81196

1.44739

1.49488

BCC32,生成檔案大小141,312B,以下時間單位ms

2.57491

1.9645

1.936

1.75218

1.51276

1.75078

1.74827

1.41862

1.44851

1.43035

2.51987

1.92119

1.93656

1.68178

1.5136

1.75022

1.75022

1.41862

1.44795

1.42951

2.57491

1.89074

2.03154

1.6815

1.5122

1.75078

1.74715

1.90639

1.44795

1.4974

可以看出,對於連加短迴圈,展開確實能帶來效能上的提升,在VC6中展開5項時的速度是不展開時的2.5倍;由於BCC32對短迴圈做了最佳化,提高不是很明顯,只有1.6倍——BCB的擁護者樂了,在這方面他們有福了,不有意最佳化的情況下,BCC32編譯的程式碼的速度是VC6的1.5倍;如果大家都寫最佳化程式碼,速度持平。

很奇怪最小代價展開的峰值是5項,而不是預計的4項,可能是第一次加法的耗時過多,這個誰能解釋一下。另外,預計浮點運算的展開應該得到更大的效能提升,實際情況並不是這樣(連1倍都沒有提高),可能是我程式碼寫得不好,誰有例子提供一下。

選用VC6的人,很多是因為它的編譯器編譯的C++程式碼是win32下效率最高的——有些人只是用它的ide環境,根本不用MFC。我不知道有沒有對應的最佳化器,不然每次自己展開太麻煩了。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-958684/,如需轉載,請註明出處,否則將追究法律責任。

相關文章