gettimeofday () mikrosaniye çözünürlükte olması garantisi var mı?

oy
82

Ben (Linux Win32 limanının OS X portunu taşıma, iyi) Linux başlangıçta Win32 API için yazılmış bir oyun, taşıma ediyorum.

Ben uygulayan QueryPerformanceCountersüreç başlatmak beri uSeconds vererek:

BOOL QueryPerformanceCounter(LARGE_INTEGER* performanceCount)
{
    gettimeofday(&currentTimeVal, NULL);
    performanceCount->QuadPart = (currentTimeVal.tv_sec - startTimeVal.tv_sec);
    performanceCount->QuadPart *= (1000 * 1000);
    performanceCount->QuadPart += (currentTimeVal.tv_usec - startTimeVal.tv_usec);

    return true;
}

Bu, ile birleştiğinde QueryPerformanceFrequency()frekans olarak sabit 1000000 vererek iyi çalışıyor benim makinede bana içeren 64 bitlik değişken vererek uSecondsprogramın açılışta beri.

Yani bu taşınabilir? Ben çekirdek böyle belirli bir şekilde veya hiçbir şeye derlendi eğer farklı çalışır keşfetmek istemiyoruz. Ben ancak, Linux dışındaki bir şey olmayan taşınabilir olması ile iyiyim.

Oluştur 01/08/2008 saat 15:36
kaynak kullanıcı
Diğer dillerde...                            


10 cevaplar

oy
54

Olabilir. Ama daha büyük sorunlarımız var. gettimeofday()(yani ntpd) zamanlayıcı değiştirmek sisteminizde süreçler varsa yanlış zamanlamalar ile sonuçlanabilir. "Normal" bir linux üzerinde olsa da, ben çözünürlüğü inanıyoruz gettimeofday()10us olduğunu. Bu ileri ve geri atlama ve zaman dolayısıyla sisteminizde çalışan süreçlere dayalı olabilir. Bu etkin hayır sorunuzun cevabını yapar.

Sen de bakması gerektiğini clock_gettime(CLOCK_MONOTONIC)aralıklarını zamanlama için. Dolayı çok çekirdekli sistemler ve harici saat ayarları gibi şeyler birkaç az konulardan muzdarip.

Ayrıca içine bakmak clock_getres()fonksiyonu.

Cevap 01/08/2008 saat 15:53
kaynak kullanıcı

oy
39

Yüksek Çözünürlüklü Intel İşlemcileri için Düşük Tepegöz Zamanlama

Intel donanım üzerinde iseniz, burada işlemci gerçek zamanlı talimat sayacını okumak için nasıl. Size işlemci boot oldu beri yürütülen CPU döngüsü sayısını söyleyecektir. Bu muhtemelen performans ölçümü için alabilirsiniz en ayrıntılı sayaç olduğunu.

Bu işlemci döngüsü sayısı olduğuna dikkat edin. linux sitesinde saniye sayısını almak için proc / cpuinfo ve ayrımın / CPU hızını alabilirsiniz. Bir ikizi bu dönüştürme oldukça kullanışlıdır.

Kutumda bu çalıştırdığınızda, ben olsun

11867927879484732
11867927879692217
it took this long to call printf: 207485

İşte Intel geliştirici kılavuzu detay ton verir.

#include <stdio.h>
#include <stdint.h>

inline uint64_t rdtsc() {
    uint32_t lo, hi;
    __asm__ __volatile__ (
      "xorl %%eax, %%eax\n"
      "cpuid\n"
      "rdtsc\n"
      : "=a" (lo), "=d" (hi)
      :
      : "%ebx", "%ecx");
    return (uint64_t)hi << 32 | lo;
}

main()
{
    unsigned long long x;
    unsigned long long y;
    x = rdtsc();
    printf("%lld\n",x);
    y = rdtsc();
    printf("%lld\n",y);
    printf("it took this long to call printf: %lld\n",y-x);
}
Cevap 02/08/2008 saat 09:08
kaynak kullanıcı

oy
18

@Bernard:

Ben senin Örneğin çoğu düz geçip üstümle, itiraf etmeliyim. Yine de derlemek yapar ve iş gibi görünüyor. Bu SMP sistemleri veya SpeedStep güvenli mi?

Ben kodu en Tamam düşünüyorum ... Güzel bir soru. Pratik açıdan, her gün benim şirkette kullanmak ve biz, kutular oldukça geniş dizisinde 2-8 çekirdek her şeyi çalıştırın. Tabii ki, YMMV, vs, ama zamanlama yöntemini (bu sistem uzaya içeriği geçiş yapmaz çünkü) güvenilir ve düşük havai gibi görünüyor.

Genellikle nasıl çalıştığı geçerli:

  • assembler olmak kod bloğunu beyan (ve uçucu, yani iyileştirici yalnız bırakacağım).
  • CPUID talimat yürütün. Bazı CPU bilgilerini (biz bir şey yapmıyoruz ki) zamanlamaları dışı sipariş yürütülmesi etkilenmez böylece CPU yürütme tamponu senkronize almanın yanı sıra.
  • rdtsc (okuma zaman damgası) yürütülmesine yürütmek. Bu işlemci yeniden beri yürütülen makine döngüsü sayısını okur. Geçerli CPU hızı ile her 194 yılda bir çevrede kaydırılır böylece bu, 64 bitlik bir değerdir. İlginç bir şekilde, orijinal Pentium referansta, onlar her 5800 yılda bir sarar not edin.
  • hatların son birkaç hi ve lo değişkenlere kayıtlarından değerlerini saklamak, ve 64-bit dönüş değeri içine koydu.

Spesifik notlar:

  • out-of-order yürütme yanlış sonuçlara neden olabilir, bu yüzden cpu hakkında bazı bilgiler veren ek olarak ayrıca herhangi dışı sipariş yürütülmesi talimatı eşitler "cpuid" talimatı yürütün.

  • başladıklarında Çoğu işletim sistemleri CPU'lar üzerinde sayaçları senkronize yüzden cevap nano birkaç saniye içinde iyidir.

  • hibernating comment muhtemelen doğrudur, ama pratikte muhtemelen kış uykusu sınırları ötesinde zamanlamaları umurumda değil.

  • ilgili speedstep: Yeni Intel CPU'lar hız değişikliklerini telafi ve bir düzeltilmiş sayımını döndürür. Bizim ağ üzerindeki kutuların bazıları üzerinde hızlı bir tarama yaptım ve onu yoktu sadece bir kutu bulundu: Bazı eski veritabanı sunucusu çalıştıran bir Pentium 3. (Bunlar linux kutuları, bu yüzden kontrol ettim: grep constant_tsc / proc / cpuinfo)

  • Ben bizim düşük seviyeli sistemler gurulara bazı AMD değerlendirmesini yaptığını biliyorum rağmen biz öncelikle Intel dükkanıysanız, AMD CPU'lar konusunda emin değilim.

o programlama bir altında çalışılmış ilginç ve (IMHO) alandır, bu merakınızı tatmin Umut. Sen Jeff ve Joel bir programcı C bilmeli olsun veya olmasın konudan bahsetmek ne biliyor? Ben, onlara bağırıyordu "hey üst düzey C şeyleri unutmak ... montajcı bilgisayar ne yaptığını bilmek istiyorsanız öğrenmek gereken budur!"

Cevap 04/08/2008 saat 01:51
kaynak kullanıcı

oy
14

Sen ilginizi çekebilir için Linux SSSclock_gettime(CLOCK_REALTIME)

Cevap 18/08/2008 saat 16:51
kaynak kullanıcı

oy
11

Şarap aslında QueryPerformanceCounter () uygulamak için gettimeofday () kullanıyor ve birçok Windows oyunları Linux ve Mac üzerinde çalışmasını sağlamak için bilinir.

başlar http://source.winehq.org/source/dlls/kernel32/cpu.c#L312

yol açar http://source.winehq.org/source/dlls/ntdll/time.c#L448

Cevap 04/08/2008 saat 15:44
kaynak kullanıcı

oy
9

Bu yüzden açıkça mikrosaniye söylüyor ama sistem saatinin çözünürlük belirtilmemiş olduğunu söylüyor. Bu bağlamda çözünürlüğü en küçük miktar şimdiye kadar artırılır nasıl gelir herhalde?

Veri yapısı bir ölçü birimi olarak mikrosaniye sahip olarak tanımlanır, ancak saat ya da işletim sistemi ince bu ölçüm aslında sahip olduğu anlamına gelmez.

Başkalarının sürmüşlerdir gibi, gettimeofday()zaman ayarı saati bükülmesine neden ve hesaplama bozabilir çünkü kötü. clock_gettime(CLOCK_MONOTONIC)İstediğiniz ve ne clock_getres()size saatinin hassasiyetini söyleyecektir.

Cevap 02/08/2008 saat 18:57
kaynak kullanıcı

oy
8

gettimeofday fiili çözünürlüklü () donanım mimarisine bağlıdır. Intel işlemcilerin yanı sıra SPARC makineleri mikrosaniye ölçen yüksek çözünürlüklü zamanlayıcılar sunuyoruz. Diğer donanım mimarileri tipik olarak 100 Hz'e ayarlanmıştır sistemin zamanlayıcı, geri düşer. Bu gibi durumlarda, zaman çözünürlüğü daha az doğru olacaktır.

Ben bu cevabı elde Yüksek Çözünürlüklü Zaman Ölçümü ve Zamanlayıcılarından, Bölüm I

Cevap 01/08/2008 saat 15:55
kaynak kullanıcı

oy
5

Bu cevap saati ile sorunlar düzeltilmiş ediliyor bahseder. Hem sizin kene birimleri garanti sorunlar ve zaman sorunlar ile C ++ 11 çözülür ayarlanır <chrono>kütüphanede.

Saat std::chrono::steady_clockdeğil garantilidir ayarlanması ve ayrıca gerçek zamanlı bir sabit bir orana ilerleyecek, böylece SpeedStep gibi teknolojiler bunu etkilemez gerekir.

Sen birine dönüştürerek türgüvenli birimleri alabilirsiniz std::chrono::durationgibi uzmanlık, std::chrono::microseconds. Bu tür kene değeri tarafından kullanılan birimleri hakkında belirsizlik olmaması. Ancak, saat mutlaka bu çözünürlüğü yoktur unutmayın. Aslında doğru bir saati kalmadan attoseconds bir süre dönüştürebilirsiniz.

Cevap 26/06/2012 saat 16:57
kaynak kullanıcı

oy
4

Tecrübelerimiz, ve ben internet üzerinden okudum kadarıyla cevap "Hayır" garanti edilmemesi edilir. Bu vb CPU hızı, işletim sistemi, Linux lezzet bağlıdır

Cevap 01/08/2008 saat 15:46
kaynak kullanıcı

oy
3

Her işlemci kendi sayacı korur ve her sayaç başka CPU göre senkronize tarafından garanti edilmez çünkü RDTSC Okuma, SMP sistemlerinde güvenilir değildir.

Ben çalışıyorum önerebiliriz clock_gettime(CLOCK_REALTIME). POSIX kılavuzu bu tüm uyumlu sistemlerde uygulanması gerektiğini gösterir. Bir nanosaniye saymak sağlayabilir, ancak muhtemelen kontrol etmek isteyecektir clock_getres(CLOCK_REALTIME)gerçek çözünürlük ne olduğunu görmek için sisteminizde.

Cevap 18/08/2008 saat 16:40
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more