2012-01-25 16 views
8

Aşağıdaki C++ kod snippet'ini (C++ kısmı, burada atlanan profiler sınıfıdır), VS2010 (64bit Intel makinesi) ile derlenmiştir. Kod basitçe bir sayısal ile yüzen (arr2) bir dizi çarpar ve başka dizide (arr1) içine sonucunu koyar:Performans, temel veri değerlerine bağlıdır.

int M = 150, N = 150; 
int niter = 20000; // do many iterations to have a significant run-time 
float *arr1 = (float *)calloc (M*N, sizeof(float)); 
float *arr2 = (float *)calloc (M*N, sizeof(float)); 

// Read data from file into arr2 

float scale = float(6.6e-14); 

// START_PROFILING 
for (int iter = 0; iter < niter; ++iter) { 
    for (int n = 0; n < M*N; ++n) {   
     arr1[n] += scale * arr2[n]; 
    } 
} 
// END_PROFILING 

free(arr1); 
free(arr2); 

okuma-dan-dosyanın parçası ve profil (yani çalışma zamanı ölçümü) 'dir basitlik için burada ihmal edildi. arr2 aralığında rasgele sayılar için başlatılır

[0 1], kod yaklaşık 10 kat daha hızlı arr2 değerlerin yaklaşık 2/3 sıfır olduğu bir seyrek dizisine başlatılan bir durum ile karşılaştırıldığında çalışır . Çalışma süresini biraz değiştiren /fp ve /O derleyici seçenekleri ile oynadım, ancak yaklaşık 1:10 oranı tutuldu.

  • Performans, gerçek değerlere nasıl bağlıdır? CPU ne farklı yapar, bu seyrek veriyi ~ 10 kat daha yavaş çalıştırır?
  • "Yavaş veri" nin daha hızlı çalışmasını sağlamanın bir yolu var mı yoksa herhangi bir eniyileme (örneğin, hesaplamanın vektör edilmesi) her iki dizide de aynı etkiye sahip olacak (yani "yavaş veri" daha yavaş çalışacak "hızlı" veri")?

DÜZENLEME

Komple kod buradadır: https://gist.github.com/1676742, derleme için komut satırı test.cpp bir açıklama yer almaktadır.

veri dosyaları

burada şunlardır: "hızlı" veriler sadece normal bir kayan nokta sayıdan oluşur, ancak sizin "yavaş" çünkü

+2

İki testin eksiksiz, tamamlanabilir sürümlerini sunabilir miyiz? – NPE

+0

Seyrek matrisinizdeki floatınıza '0' ilettiğinizde, int 'den' float 'dönüşümü bazı ek yükleri tanıtır mı? –

+0

Yalnızca 0 olmayan öğeleri mi güncellersiniz? Yani, sıfırlar önbellekte olmayabilir mi? – duedl0r

cevap

7

Muhtemelen de bu veri içeriyor çok sayıda denormalize sayı.

İkinci soruya gelince, bununla hızını artırmak için deneyin (ve tam sıfır gibi tüm denormalized numaraları tedavi) olabilir: Bunun için iki nedeni

#include <xmmintrin.h> 
_mm_setcsr(_mm_getcsr() | 0x8040); 
+0

Evet, eğer 'ölçek' yükselirse, yavaş veri çok daha hızlı olur .. – duedl0r

2

düşünebiliriz. İlk olarak, şube yordayıcısı yanlış kararlar veriyor olabilir. Bu, kod değişiklikleri olmadan veri değişikliklerinden kaynaklanan olası bir performans boşluğu nedenidir. Ancak, bu durumda, çok olası görünmüyor.

İkinci olası neden, "çoğunlukla sıfırlar" verilerinizin sıfırlardan ibaret olmadığını, neredeyse sıfırlardan oluşmadığını ya da neredeyse sıfır aralığında arr1 tuttuğunuz olmasıdır. Bakınız this Wikipedia link.

+0

Düşünmeyin - testler çalıştırın. –

1

I.bin'den gelen verilerin işlenmesinin daha uzun sürmesi garip bir şey yoktur: '1.401e-045 # DEN' veya '2.214e-043 # DEN' gibi çok sayıda numaranız var. standart şamandıra hassasiyetine normalleştirilemez. 6.6e-14 ile çarpacağınız göz önünde bulundurulduğunda, kesinlikle hesaplamaların önemli ölçüde yavaşladığı, yetersiz özel durumlara sahip olursunuz.

İlgili konular