SORU
31 Mart 2010, ÇARŞAMBA


Kayan modern donanım vs tamsayı hesaplamaları noktası

C bazı kritik performans işi yapıyorum ve şu anda doğal olarak çünkü kayan nokta sorunları için tamsayı hesaplamaları kullanıyoruz "". onun daha hızlı Bu can sıkıcı sorunları bir sürü neden olur ve sinir bozucu bir sürü kod ekler.

Şimdi, isteğe bağlı co-işlemci olduğunu nasıl kayan nokta hesaplamaları çok yavaştı yaklaşık yaklaşık yaklaşık okuma inanıyorum nerede 386 gün, (IIRC) hatırlıyorum. Ama şüphesiz günümüzde katlanarak daha karmaşık ve güçlü İşlemciler ile hiçbir fark yapar "hızlı kayan yapıyor" veya hesaplama noktası tamsayı? Özellikle gerçek hesaplamadan sonra zaman potansiyel bir durak neden ya da ana bellekten bir şey alma gibi bir şey kıyasla çok daha küçük.

Doğru cevap bu test etmek için iyi bir yol olurdu ne hedef donanım, kriter olduğunu biliyorum? İki küçük C Program yazdım ve "Linux, ama zaman çok değişkendir gerçek çalıştırmak (sanal sunucu çalıştırıyorum yardımcı olmuyor). zaman onların zamanı karşılaştırıldığında Harcamaların kısa bütün günümü kriterler yüzlerce çalışan, grafikler vb yapmak. göreli hızı makul bir test almak için yapabileceğim bir şey var mı? Herhangi bir fikir ya da düşünce? Tamamen yanlış mıyım?

Olarak kullandığım programlar, bir vesile ile aynı değil, şöyle:

#include <iostream>
#include <cmath>
#include <cstdlib>
#include <time.h>

int main( int argc, char** argv )
{
    int accum = 0;

    srand( time( NULL ) );

    for( unsigned int i = 0; i < 100000000;   i )
    {
        accum  = rand( ) % 365;
    }
    std::cout << accum << std::endl;

    return 0;
}

Program 2:

#include <iostream>
#include <cmath>
#include <cstdlib>
#include <time.h>

int main( int argc, char** argv )
{

    float accum = 0;
    srand( time( NULL ) );

    for( unsigned int i = 0; i < 100000000;   i )
    {
        accum  = (float)( rand( ) % 365 );
    }
    std::cout << accum << std::endl;

    return 0;
}

Şimdiden teşekkürler!

Edit: düzenli 86 ya 86-64 Linux ve Windows masaüstü makinelerde çalışan değer verdiğim platform.

Edit 2(açıklama aşağıda yapıştırılan): geniş bir kod Bankası şu anda var. Gerçekten ben gelip karşı genelleme biz "olmamalıdır kullanın şamandıra beri tamsayı hesaplama daha hızlı" - arıyorum (eğer bu doğru bile) çürütmek bu yaygın varsayım. Kesin sonuç tüm işi yapıyor ve daha sonra bu profil, kısa tahmin etmek imkansız olacağını fark ettim.

Her neyse, tüm mükemmel cevaplar ve yardımlarınız için teşekkürler. Ücretsiz başka bir şey ekleyin:) hissediyorum.

CEVAP
31 Mart 2010, ÇARŞAMBA


Örnek (daha küçük sayılar daha hızlı)

64-bit Intel Xeon X5550 @ 2.67, 4.1.2 -O3 GHz gcc

short add/sub: 1.005460 [0]
short mul/div: 3.926543 [0]
long add/sub: 0.000000 [0]
long mul/div: 7.378581 [0]
long long add/sub: 0.000000 [0]
long long mul/div: 7.378593 [0]
float add/sub: 0.993583 [0]
float mul/div: 1.821565 [0]
double add/sub: 0.993884 [0]
double mul/div: 1.988664 [0]

32-bit Çift Çekirdekli AMD Opteron(tm) İşlemci 265 @ 1.81 GHz, 3.4.6 -O3 KİK

short add/sub: 0.553863 [0]
short mul/div: 12.509163 [0]
long add/sub: 0.556912 [0]
long mul/div: 12.748019 [0]
long long add/sub: 5.298999 [0]
long long mul/div: 20.461186 [0]
float add/sub: 2.688253 [0]
float mul/div: 4.683886 [0]
double add/sub: 2.700834 [0]
double mul/div: 4.646755 [0]

Dan pointed out, hatta bir kez saat frekansı için ardışık tasarımlar kendini yanıltıcı olabilir) normalize gibisonuçlar çılgınca İŞLEMCİ mimarisine göre değişir(bireyselALU/FPU performans,sıragerçekAlu sayısı/FPUstüm işlemler aşağıda superscalar kaç independent operations can execute in parallel -- ikinci faktör kod tarafından icra değil etkileyen tasarımlar çekirdek başına kullanılabilir aşağıda sırayla bağlıdır.)

Zavallı adamın DEĞERLERİ/ALU işlemi kriter:

#include <stdio.h>
#ifdef _WIN32
#include <sys/timeb.h>
#else
#include <sys/time.h>
#endif
#include <time.h>

double
mygettime(void) {
# ifdef _WIN32
  struct _timeb tb;
  _ftime(&tb);
  return (double)tb.time   (0.001 * (double)tb.millitm);
# else
  struct timeval tv;
  if(gettimeofday(&tv, 0) < 0) {
    perror("oops");
  }
  return (double)tv.tv_sec   (0.000001 * (double)tv.tv_usec);
# endif
}

template< typename Type >
void my_test(const char* name) {
  Type v  = 0;
  // Do not use constants or repeating values
  //  to avoid loop unroll optimizations.
  // All values >0 to avoid division by 0
  // Perform ten ops/iteration to reduce
  //  impact of   i below on measurements
  Type v0 = (Type)(rand() % 256)/16   1;
  Type v1 = (Type)(rand() % 256)/16   1;
  Type v2 = (Type)(rand() % 256)/16   1;
  Type v3 = (Type)(rand() % 256)/16   1;
  Type v4 = (Type)(rand() % 256)/16   1;
  Type v5 = (Type)(rand() % 256)/16   1;
  Type v6 = (Type)(rand() % 256)/16   1;
  Type v7 = (Type)(rand() % 256)/16   1;
  Type v8 = (Type)(rand() % 256)/16   1;
  Type v9 = (Type)(rand() % 256)/16   1;

  double t1 = mygettime();
  for (size_t i = 0; i < 100000000;   i) {
    v  = v0;
    v -= v1;
    v  = v2;
    v -= v3;
    v  = v4;
    v -= v5;
    v  = v6;
    v -= v7;
    v  = v8;
    v -= v9;
  }
  // Pretend we make use of v so compiler doesn't optimize out
  //  the loop completely
  printf("%s add/sub: %f [%d]\n", name, mygettime() - t1, (int)v&1);
  t1 = mygettime();
  for (size_t i = 0; i < 100000000;   i) {
    v /= v0;
    v *= v1;
    v /= v2;
    v *= v3;
    v /= v4;
    v *= v5;
    v /= v6;
    v *= v7;
    v /= v8;
    v *= v9;
  }
  // Pretend we make use of v so compiler doesn't optimize out
  //  the loop completely
  printf("%s mul/div: %f [%d]\n", name, mygettime() - t1, (int)v&1);
}

int main() {
  my_test< short >("short");
  my_test< long >("long");
  my_test< long long >("long long");
  my_test< float >("float");
  my_test< double >("double");

  return 0;
}

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • FILIPeeeK

    FILIPeeeK

    22 Mayıs 2006
  • FrankJavCee

    FrankJavCee

    29 Kasım 2008
  • Vortez

    Vortez

    27 Temmuz 2009