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;
}
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 :( –
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) . –
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