2016-06-26 7 views
0

Lets sagen, dass ich diese Funktion haben, die mehrere Threads müssen in einer Art GleichschrittAlternative Barriere gegen Spinlock?

std::atomic<bool> go = false; 

void func() { 
     while (!go.load()) {} //sync barrier 
     ... 
} 

Ich möchte loszuwerden, die spinlock und ersetzen Sie es für etwas Mutex Basis laufen, da ich viele Threads zu tun Alle Arten von Sachen und Spinlocking von einem Dutzend Threads ist katastrophal für den Gesamtdurchsatz, es läuft viel schneller, wenn ich zum Beispiel Sleep (1) innerhalb des Spinlocks einschließe.

Also gibt es etwas in STL, das in HLSL zum Beispiel AllMemoryBarrierWithGroupSync() ähnlich wäre? Im Grunde würde es jeden Faden an der Schranke schlafen lassen, bis alle ihn erreicht haben.

+0

Für was es wert ist, 'while (! Go.load())' kann geschrieben werden, während (! Go) '. –

Antwort

0

Es klingt wie Sie genau tun wollen, was eine Bedingung Variable für gut ist.

bool go = false; 
std::mutex mtx; 
std::condition_variable cv; 

void thread_func() 
{ 
    { 
     std::unique_lock<std::mutex> lock(mtx); 
     cv.wait(lock, []{ return go; }); 
    } 
    // Do stuff 
} 

void start_all() 
{ 
    { 
     std::unique_lock<std::mutex> lock(mtx); 
     go = true; 
    } 
    cv.notify_all(); 
} 
0

Wenn Sie bereit sind, experimentelle Funktionen zu verwenden, dann helfen Ihnen latch oder barrier. Andernfalls könnten Sie Ihr eigenes ähnliches Konstrukt erstellen, indem Sie oder conditional_variable_any mit shared_lock (C++ 17-Feature) verwenden.

shared_mutex Unter Verwendung einer Barriere zu implementieren:

#include <condition_variable> 
#include <iostream> 
#include <mutex> 
#include <shared_mutex> 
#include <thread> 
#include <vector> 

std::shared_mutex mtx; 
std::condition_variable_any cv; 
bool ready = false; 

void thread_func() 
{ 
    { 
     std::shared_lock<std::shared_mutex> lock(mtx); 
     cv.wait(lock, []{return ready;}); 
    } 
    std::cout << '0'; 
    //Rest of calculations 
} 


int main() 
{ 
    std::vector<std::thread> threads; 
    for(int i = 0; i < 5; ++i) 
     threads.emplace_back(thread_func); 
    std::this_thread::sleep_for(std::chrono::seconds(1)); 
    { 
     std::unique_lock<std::shared_mutex> lock(mtx); 
     std::cout << "Go\n"; 
     ready = true; 
    } 
    cv.notify_all(); 
    for(auto& t: threads) 
     t.join(); 
    std::cout << "\nFinished\n"; 
}