為什么我的程序在完全循環8192個元素時會變慢?以下是相關程序的摘錄。矩陣img[][]的大小為SIZE×SIZE,并在以下位置初始化:img[j][i] = 2 * j + i然后,你創建一個矩陣res[][],這里的每個字段都是img矩陣中它周圍9個字段的平均值。為簡單起見,邊框保留為0。for(i=1;i<SIZE-1;i++)
for(j=1;j<SIZE-1;j++) {
res[j][i]=0;
for(k=-1;k<2;k++)
for(l=-1;l<2;l++)
res[j][i] += img[j+l][i+k];
res[j][i] /= 9;}這就是該計劃的全部內容。為了完整起見,以下是之前的內容。沒有代碼。如您所見,它只是初始化。#define SIZE 8192float img[SIZE][SIZE]; // input imagefloat res[SIZE][SIZE]; //result of mean filterint i,j,k,l;for(i=0;i<SIZE;i++)
for(j=0;j<SIZE;j++)
img[j][i] = (2*j+i)%8196;基本上,當SIZE是2048的倍數時,此程序很慢,例如執行時間:SIZE = 8191: 3.44 secs
SIZE = 8192: 7.20 secs
SIZE = 8193: 3.18 secs編譯器是GCC。據我所知,這是因為內存管理,但我對這個主題并不太了解,這就是我在這里問的原因。另外如何解決這個問題會很好,但如果有人能解釋這些執行時間,我已經足夠開心了。我已經知道malloc / free了,但問題不在于使用的內存量,它只是執行時間,所以我不知道這會有多大幫助。
2 回答

開心每一天1111
TA貢獻1836條經驗 獲得超13個贊
差異是由以下相關問題引起的相同超對齊問題引起的:
但那只是因為代碼還有另外一個問題。
從原始循環開始:
for(i=1;i<SIZE-1;i++) for(j=1;j<SIZE-1;j++) { res[j][i]=0; for(k=-1;k<2;k++) for(l=-1;l<2;l++) res[j][i] += img[j+l][i+k]; res[j][i] /= 9;}
首先注意兩個內環是微不足道的。它們可以按如下方式展開:
for(i=1;i<SIZE-1;i++) { for(j=1;j<SIZE-1;j++) { res[j][i]=0; res[j][i] += img[j-1][i-1]; res[j][i] += img[j ][i-1]; res[j][i] += img[j+1][i-1]; res[j][i] += img[j-1][i ]; res[j][i] += img[j ][i ]; res[j][i] += img[j+1][i ]; res[j][i] += img[j-1][i+1]; res[j][i] += img[j ][i+1]; res[j][i] += img[j+1][i+1]; res[j][i] /= 9; }}
這樣就留下了我們感興趣的兩個外環。
現在我們可以看到問題在這個問題中是一樣的:為什么在迭代2D數組時,循環的順序會影響性能?
您是按列而不是按行迭代矩陣。
要解決此問題,您應該交換兩個循環。
for(j=1;j<SIZE-1;j++) { for(i=1;i<SIZE-1;i++) { res[j][i]=0; res[j][i] += img[j-1][i-1]; res[j][i] += img[j ][i-1]; res[j][i] += img[j+1][i-1]; res[j][i] += img[j-1][i ]; res[j][i] += img[j ][i ]; res[j][i] += img[j+1][i ]; res[j][i] += img[j-1][i+1]; res[j][i] += img[j ][i+1]; res[j][i] += img[j+1][i+1]; res[j][i] /= 9; }}
這完全消除了所有非順序訪問,因此您不再在大功率二次上獲得隨機減速。
酷睿i7 920 @ 3.5 GHz
原始代碼:
8191: 1.499 seconds8192: 2.122 seconds8193: 1.582 seconds
互換的外循環:
8191: 0.376 seconds8192: 0.357 seconds8193: 0.351 seconds
添加回答
舉報
0/150
提交
取消