SORU
4 EYLÜL 2012, Salı


Neden benim program tam olarak 8192 elemanları döngü içinde zaman yavaş?

Burada söz konusu programın özü bu. 8* *matriks büyüklüğü X BOYUT ve başlatıldı

img[j][i] = 2 * j i

O zaman, bir matris res[][], ve burada her alan ımg matrix'te çevresinde 9 alanların ortalama olarak yapılır. Sınır basitlik için 0 kalır.

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;
}

Bu program var. Bütünlüğü hatırına, daha önce buraya gelir. Kod sonra gelir. Gördüğünüz gibi, sadece başlatma.

#define SIZE 8192
float img[SIZE][SIZE]; // input image
float res[SIZE][SIZE]; //result of mean filter
int i,j,k,l;
for(i=0;i<SIZE;i  ) 
    for(j=0;j<SIZE;j  ) 
        img[j][i] = (2*j i)96;

Temel olarak, bu program BOYUTU 2048, örneğin yürütme kere çok yavaş

SIZE = 8191: 3.44 secs
SIZE = 8192: 7.20 secs
SIZE = 8193: 3.18 secs

Derleyici GCC. Bildiğim kadarıyla bu bellek yönetimi yüzünden, ama gerçekten burada soruyorum neden ki bu konu hakkında çok fazla şey bilmiyorum.

Ayrıca düzeltmek için nasıl bu güzel olurdu, ama eğer birisi bu yürütme kez açıklamak, zaten yeterince mutlu olurdum.

Ben zaten malloc/ücretsiz biliyorum, ama sorun bir bellek miktarı kullanılmaz, sadece yürütme zamanı, bunun yardımı olacağını bilmiyorum.

CEVAP
4 EYLÜL 2012, Salı


Fark aşağıdaki ilgili sorular: süper uyum aynı sorun nedeniyle oluşur

Ama tek kod ile başka bir sorun var çünkü.

Orijinal döngü başlayarak:

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;
}

İlk iki iç döngüler önemsiz olduğuna dikkat edin. Aşağıdaki gibi içe kıvrık olabilir

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;
    }
}

Bu iki ilgileniyoruz dış-döngüler kalıyor.

Sorun aynı olduğunu görebiliriz şimdi bu soru içinde: Why does the order of the loops affect performance when iterating over a 2D array?

Matris sütun-bilge row-wise yerine yineleme.


Bu sorunu çözmek için, iki döngüler değişimi gerekir.

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;
    }
}

Bu sıralı olmayan tüm erişim artık rastgele, bu yüzden tamamen yavaşlamaya büyük güçler iki ortadan kaldırır.


@ 3.5 GHz Core i7 920

Orijinal kodu:

8191: 1.499 seconds
8192: 2.122 seconds
8193: 1.582 seconds

Dış Döngüler Değiştirilmiştir:

8191: 0.376 seconds
8192: 0.357 seconds
8193: 0.351 seconds

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • GavinMichaelBooth

    GavinMichael

    26 AĞUSTOS 2006
  • hockeywebcasts

    hockeywebcas

    31 EKİM 2012
  • Within Temptation

    Within Tempt

    18 EYLÜL 2006