SORU
6 EKİM 2009, Salı


Neden SSE x * Karekök(x) rsqrt daha yavaş(x) skaler mi?

Ben profil bazı temel matematik Intel Core Duo ve süre bakıyor çeşitli yaklaşımlar Karekök fark ettim garip bir şey: kullanarak SSE skaler işlemler, daha hızlı bir karşılıklı çarpma ve Karekök alma Karekök, daha kullanmak için yerel Karekök işlem kodu!

Gibi bir döngü ile test ediyorum:

inline float TestSqrtFunction( float in );

void TestFunc()
{
  #define ARRAYSIZE 4096
  #define NUMITERS 16386
  float flIn[ ARRAYSIZE ]; // filled with random numbers ( 0 .. 2^22 )
  float flOut [ ARRAYSIZE ]; // filled with 0 to force fetch into L1 cache

  cyclecounter.Start();
  for ( int i = 0 ; i < NUMITERS ;   i )
    for ( int j = 0 ; j < ARRAYSIZE ;   j )
    {
       flOut[j] = TestSqrtFunction( flIn[j] );
       // unrolling this loop makes no difference -- I tested it.
    }
  cyclecounter.Stop();
  printf( "%d loops over %d floats took %.3f milliseconds",
          NUMITERS, ARRAYSIZE, cyclecounter.Milliseconds() );
}

Bu TestSqrtFunction için birkaç farklı organları ile bunu denedim, ve gerçekten kafamı kurcalıyor bazı zamanlamalar var. Şimdiye kadar en kötüsü yerli Karekök kullanıyordu() fonksiyonu ve icar """". optimize derleyici akıllı 24ns/şamandıra, x 87 bu DEĞERLERİ kullanarak bu zavallı kötü oldu:

inline float TestSqrtFunction( float in )
{  return sqrt(in); }

Denedim bir sonraki şey bir iç derleyici SSE. skaler Karekök işlem kodu kullanmaya zorlamak için kullanıyordu:

inline void SSESqrt( float * restrict pOut, float * restrict pIn )
{
   _mm_store_ss( pOut, _mm_sqrt_ss( _mm_load_ss( pIn ) ) );
   // compiles to movss, sqrtss, movss
}

Bu daha iyi, 11.9 ns/şamandıra idi. Ben de 2'de 1 hata ile olsa da 4.3 ns/yüzer de donanım daha iyi koştu Carmack's wacky Newton-Rhapson approximation technique,, çalıştı10çok fazla benim amaçlar için kullanılan).

O kadından SSE için op çalıştığımda oldukarşılıklıKarekök ve Kare Kök ( x * 1/&radiç;x = &radiç;x) elde etmek için kullanılan çarpın. Bu iki bağımlı operasyonlar sürüyor olsa da, 2 en hızlı çözümün bu kadar 1.24 de ns/yüzer ve doğruydu-14:

inline void SSESqrt_Recip_Times_X( float * restrict pOut, float * restrict pIn )
{
   __m128 in = _mm_load_ss( pIn );
   _mm_store_ss( pOut, _mm_mul_ss( in, _mm_rsqrt_ss( in ) ) );
   // compiles to movss, movaps, rsqrtss, mulss, movss
}

Benim soru temeldene verir?Neden SSE---donanım inşa Karekök işlem koduyavaşdiğer iki matematik işlemleri dışında sentezleme daha?

Bu teyit ettim çünkü gerçekten op kendisinin maliyeti olduğuna eminim

  • Tüm veri önbelleği sığar, ve erişir sıralı
  • fonksiyonları inlined
  • bu döngü çözümü hiç fark etmez
  • derleyici bayrakları tam optimizasyon (ve aksamı iyidir, kontrol ettim) ayarlanır

(edit: stephentyrone doğru işaret işlemleri uzun dizeleri numaraları kullanmanız gerekir vectorizing SIMD dolu ops, gibi rsqrtps - ama dizi veri yapısı burada olduğu için test amaçlı sadece: ya ben çok çalışıyorum ölçüsüdürskalervectorized bu kodu kullanmak için bir performans.)

CEVAP
6 EKİM 2009, Salı


sqrtss düzgün yuvarlak bir sonuç verir. rsqrtss veriryaklaşımyaklaşık 11 bit hassasiyetinde karşılıklı için.

sqrtss çok daha doğru bir sonuç, doğruluk gerektiğinde için üretiyor. rsqrtss yaklaşık yeterlidir durumlar için var, ama hız gereklidir. Eğer okuduğunuz Intel belgelerine, sen de bul bir talimat dizisi (karşılıklı Karekökü yaklaşımı ve ardından bir tek Newton-Raphson adım) veren, neredeyse tam hassas (~23 bit doğruluk diye hatırlıyorum doğru), ve hala biraz daha hızlı sqrtss.

düzenleme:Eğer hız, kritik, ve sen gerçekten aramış bu bir döngü için birçok değerleri olmalısınız kullanarak vectorized sürümleri bu talimatlar, rsqrtps sqrtps, hem hangi işlemi dört yüzer başına talimat.

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Attempts at least

    Attempts at

    1 Ocak 2007
  • LinusTechTips

    LinusTechTip

    25 Kasım 2008
  • LiquidMusick

    LiquidMusick

    23 Aralık 2010