2016-04-19 10 views
0

Ich habe eine task Klasse, die ich muss beweglich sein. Ich habe ungefähr 10-15 Aufgaben, die in einer Elternklasse task_storage enthalten sind. Innerhalb task::execute() muss ich warten, eine atomare Variable Null zu erreichen:Std :: Mutex und Std :: Condition_Variable Konstruktion Overhead vs Heap-Zuweisung

void task::execute() 
{ 
    for_subtasks([this] 
     { 
      thread_pool.post([this] 
       { 
        this->do_work(); 

        // Atomic counter. 
        --(this->_remaining_subtasks); 
       }); 
     }); 

    // wait for `_remaining_subtasks == 0` 
} 

Ich habe drei Alternativen gedacht für _remaining_subtasks == 0 zu warten, während task halten beweglich:

  1. Verwenden Sie eine while(...){ sleep(1); } beschäftigt Warteschleife.

  2. Konstruieren und verwenden Sie eine std::mutex und eine std::condition_variable innerhalb der Funktion.

    void task::execute() 
    { 
        std::mutex m; 
        std::condition_variable cv; 
    
        for_subtasks(/* ... */); 
    
        std::unique_lock<std::mutex> l(m); 
        cv.wait(l, [this]{ return this->_remaining_subtasks == 0; }); 
    } 
    
  3. Speichern eines std::unique_ptr<std::mutex> und ein std::unique_ptr<std::condition_variable> innen task als Felder. Dies würde ermöglichen, dass task beweglich ist, aber auch Indirection einführen, um auf die Synchronisationsgrundelemente zuzugreifen.

    void task::execute() 
    { 
        for_subtasks(/* ... */); 
    
        std::unique_lock<std::mutex> l(*this->_m); 
        this->_cv.wait(l, [this]{ return this->_remaining_subtasks == 0; }); 
    } 
    

Ich beabsichtige nicht, beschäftigt Warte auf verwenden. Ich habe versucht, die schnellste Lösung zwischen 2 und 3 zu erstellen, konnte aber kein sinnvolles Ergebnis erzielen.

Ist der Konstruktionsaufwand für std::mutex und std::condition_variable von Bedeutung? Oder wären die Heap-Zuweisungen/Zugriffe langsamer?

Antwort

1

Ist der Konstruktionsaufwand für std :: mutex und std :: condition_variable signifikant? Oder wären die Heap-Zuweisungen/-Zugriffe langsamer?

In beiden Fällen müssen Konstruktoren aufgerufen werden. Der Unterschied ist, wo der Speicher zugeordnet ist: statischer Speicher, Stack oder Heap. Die Zuteilung von Heap ist die langsamste.

Unter Linux und POSIX-kompatiblen Systemen, std::mutex und std::condition_variable sind dünne Wrapper über POSIX pthread_mutex_t und pthread_cond_t Strukturen. Das Initialisieren dieser Strukturen beinhaltet das Festlegen von Elementvariablen mit grundlegenden Typen und ohne Aufrufe. Mit anderen Worten, die Konstruktion ist billig.