2009-09-24 10 views
9

Ben Windows Interlocked işlevleri kullanarak çok basit bir sayaç kilidi yapılan ve bir çift çekirdekli CPU üzerinde (bir şekilde arttıracaktır iki konuları) bunu test raporları;Intel Müfettiş benim spinlock uygulanmasında veri yarış

programı Tamam iş gibi görünüyor (Bu aynı sonucu hiçbir senkronizasyon kullanılan durum böyle değil her zaman verir), fakat Intel Müfettişdeğeri + = j bir yarış durumu olduğunu söylüyor Paralel (aşağıdaki kodya bakın). Uyarı, SpinLock'um yerine Kritik Bölümler kullanılırken kayboluyor.

spinlock benim uygulamamın doğru mu değil mi? Gerçekten garip, çünkü kullanılan tüm operasyonlar atomik ve uygun hafıza bariyerlerine sahip ve yarış koşullarına yol açmamalı.

class SpinLock 
{ 
    int *lockValue; 
    SpinLock(int *value) : lockValue(value) { } 

    void Lock() { 
     while(InterlockedCompareExchange((volatile LONG*)lockValue, 1, 0) != 0) { 
      WaitABit(); 
     } 
    } 

    void Unlock() { InterlockedExchange((volatile LONG*)lockValue, 0); } 
}; 

test programı:

static const int THREADS = 2; 
HANDLE completedEvents[THREADS]; 
int value = 0; 
int lock = 0; // Global. 

DWORD WINAPI TestThread(void *param) { 
    HANDLE completed = (HANDLE)param; 
    SpinLock testLock(&lock); 

    for(int i = 0;i < 1000*20; i++) { 
     for(int j = 0;j < 10*10; j++) { 
      // Add something to the variable. 
      testLock.Lock(); 
      value += j; 
      testLock.Unlock(); 
     } 
    } 
    SetEvent(completed); 
} 

int main() { 
    for(int i = 0; i < THREADS; i++) { 
     completedEvents[i] = CreateEvent(NULL, true, false, NULL); 
    } 
    for(int i = 0; i < THREADS; i++) { 
     DWORD id; 
     CreateThread(NULL, 0, TestThread, completedEvents[i], 0, &id); 
    } 

    WaitForMultipleObjects(THREADS, completedEvents, true, INFINITE); 
    cout<<value; 
} 

cevap

4
data race için

Paralel Müfettişlik belgelerine kritik bölüm veya mutex kullanarak önerir Windows'da yarışları düzeltmek için. Paralel Denetçinin, icat edebileceğin diğer kilitleme mekanizmalarını nasıl tanıyacağını bildiğini gösteren hiçbir şey yok. roman kilitleme mekanizmalarının analizi için

Araçlar kodu ile olası her yolu bakmak statik araçlar olma eğilimindedir, Paralel Müfettişlik belgelerine bir zamanlar kodu çalıştırır anlamına gelir. Eğer roman kilitleme mekanizmaları ile deney yapmak istiyorsanız

, ben akademik literatürde kullanılan gördüğüm en yaygın aracı Spin model checker olduğunu. Orada devlet alanını azaltacak ESP, ayrıca, ama eşzamanlı problemlere uygulanmış mı onu da bilmiyorum ve ayrıca pi-matematikten kanepe sorununuzu eğer bir analiz verecekti mobility workbench. Intel Paralel Denetçisi, bu araçlar kadar karmaşık bir şey gibi görünmüyor, ancak sezgisel yöntemleri kullanarak yaygın olarak ortaya çıkan sorunları kontrol etmek için tasarlandı. Bana benzer durumda diğer fakir millet için

1

Ben şöyle de uygulanmalıdır eminim:

class SpinLock 
{ 
    long lockValue; 
    SpinLock(long value) : lockValue(value) { } 

    void Lock() { 
     while(InterlockedCompareExchange(&lockValue, 1, 0) != 0) { 
      WaitABit(); 
     } 
    } 

    void Unlock() { InterlockedExchange(&lockValue, 0); } 
}; 
+0

Ne önerdi hakkında etrafta, sadece o int ne ile aynıdır Kilit spinleri sınıfta yer alıyor ... ve bu RAII artık kullanılamayacağından bir dezavantaj olacaktır (sınıf ayrıca kilidi otomatik olarak serbest bırakan bir yıkıcıya da sahiptir). Düşünce, söylediklerini denedim, ve aynı: Program doğru çalışıyor, ama Intel Paralel Denetçisi bir yarış durumu olduğunu söylüyor. Belki de Müfettişin bir hatası var mı? Muhtemelen :( –

+0

da açık cast yapmak yerine başlamak için uzun süre kullanmalısınız ve kurucuda hiçbir parametre alamazsınız ve sadece kilidini açmaya başlayabilirsiniz.İhtiyaç yaratan şey başlangıçta kilitlenmişse, sadece oluşturduktan sonra ama onu paylaşmadan önce kilitleyin. @Igratian - Bu durumda RAI'ye ihtiyacınız yok çünkü yıkıcı hiçbir şey temizlemeyecek (sadece uzun) . –

+0

Düzenlendi.Bu soru, dekodrötörün eklenmesini rahatsız etmeyecek ... çünkü soru, onun kodunu tamamen düzeltmeyi garanti etmiyor. Sadece meselesini çözmeye çalışıyordum. – Goz

2

: içerir ve tam olarak bu tür bir şey yapmak için kütüphaneler Intel kümesi sağlamak ETMEZ. Bu materyaller için Inspector kurulum dizininde (kurulum dizininde \ include, \ lib32 ve \ lib64 \ 'ı göreceksiniz) kontrol edin. (2014 Aralık itibariyle) bunların nasıl kullanılacağı ile ilgili Dokümantasyon:

https://software.intel.com/sites/products/documentation/doclib/iss/2013/inspector/lin/ug_docs/index.htm#GUID-E8B4A8F7-45C3-489C-A5E3-1C9CC525BA9C.htm

3 işlevleri vardır:

void __itt_sync_acquired(void *addr) 
void __itt_sync_releasing(void *addr) 
void __itt_sync_destroy(void *addr) 
+0

Bunu kendi spin-lock muteksimle test ettim ve beklendiği gibi çalışıyor (Paralel Müfettiş raporundan veri yarışı yok) – Julio

+0

Bir şey değil. – johnwbyrd

İlgili konular