2016-06-26 8 views
0

Zum Beispiel, hier ist mein Thread Barriere/Abschnittsart SacheKann ich einige Variablen Vorlage spezifisch machen?

template <bool switchable = false, bool counting = false> 
struct SimpleBarrier { 
private: 
    std::mutex mtx; 
    std::condition_variable cv; 
    std::atomic<bool> enabled; 
    std::atomic<int> inside; 

public: 
    SimpleBarrier() { 
     if (switchable) enabled.store(true, std::memory_order_release); 
     if (counting) inside.store(0, std::memory_order_release); 
    } 

    void enter() { 
     if (switchable && !enabled.load(std::memory_order_acquire)) return; 
     if (counting) inside.fetch_add(1, std::memory_order_acq_rel); 
     std::unique_lock<std::mutex> lock(mtx); 
     cv.wait(lock); 
    } 

    void leave() { 
     if (counting) inside.fetch_sub(1, std::memory_order_acq_rel); 
    } 

    void release() { 
     cv.notify_all(); 
    } 

    void enable() { 
     if (switchable) { 
      enabled.store(true, std::memory_order_release); 
     } 
    } 

    void disable() { 
     if (switchable) { 
      enabled.store(false, std::memory_order_release); 
     } 
    } 

    bool is_empty() { 
     if (counting) return inside.load(std::memory_order_acquire) == 0; 
     return false; 
    } 
}; 

Anfangs wie „SwitchableBarrier“ und „CountingSection“ usw. Ich wollte nur ein paar Klassen machen, aber dann begann ich Kombinationen wie „SwitchableCountingSection benötigen "Und es wird wahrscheinlich mehr Qualitäten geben. Um ein Dutzend Klassen zu vermeiden, habe ich sie mithilfe von Template-Parametern in eine Klasse gerollt, um bestimmte Qualitäten ein- und auszuschalten.

Die Verwendung von Vorlagenparametern als Bedingung ermöglicht es dem Compiler, ungenutzte Qualitäten zu optimieren, so dass kein zusätzlicher Aufwand von unbenutzten erzeugt wird. Die Frage ist jedoch - ist es möglich, auch Klassenvariablen zu optimieren?

Nimm die Variable "inside" zum Beispiel, wenn sie == false zählt, dann ist sie völlig nutzlos und muss nicht da sein. Kann ich Template-Parameter-spezifische Klassenvariablen haben?

+0

Definieren Sie eine Template-Spezialisierung für 'counting == false'? – songyuanyao

Antwort

0

Jedes Mitglied, auch wenn es nicht benutzt wird, hat eine andere Adresse. Außerdem wird der Compiler es nicht entfernen. Es gibt jedoch einen einfachen Trick: Leere Basen müssen nicht ihre eigene Adresse bekommen. Wenn das mit Spezialisierung kombiniert wird, können Sie alle Daten loswerden. Zum Beispiel:

template <bool, typename T> 
class conditional_count { 
    std::atomic<T> value; 
public: 
    T load_count() { return value.load(std::memory_order_aquire); } 
    void store_count(T v) { value.store(v, std::memory_order_release); } 
    // ... 
}; 
template <typename T> 
struct conditional_count<false, T> { 
    int load_count() { return 0; } 
    void store_count(T) {} 
    // ... 
}; 

template <bool switchable = false, bool counting = false> 
struct SimpleBarrier 
    : private conditional_count<counting> { 
    // use this->load_count(), this->store_count(), etc. 
}; 

Es wäre möglich, eine allgemeinere conditional_atomic<...> zu schaffen, aber es würde erfordern einen zusätzlichen Tag-Typ nehmen zu identifizieren, welches benutzt wird, und es wird ein bisschen ärgerlich zu verwenden. Der allgemeine Ansatz besteht jedoch darin, die Logik in eine Basis mit geeigneten Funktionen zu setzen, um auf die Variable zuzugreifen und eine Spezialisierung bereitzustellen, die nichts tut.

Verwandte Themen