2016-06-26 6 views
0
例えば

は、ここで私はちょうどなど「SwitchableBarrier」と「CountingSection」のようなクラスの束を作るつもりだったが、その後、私は「SwitchableCountingSectionのような組み合わせを必要とし始めた当初は、私のスレッドバリア/セクションタイプのもの一部の変数テンプレートを特定にすることはできますか?

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; 
    } 
}; 

ですおそらく十数クラスを作ることを避けるために、より質の高いものになるでしょう。テンプレートパラメータを使用してそれらを1つのクラスにロールして、特定の品質をオン/オフにします。

テンプレートパラメータを条件として使用すると、コンパイラは未使用の品質を最適化して、未使用のものから余分なオーバーヘッドを取り除くことができます。問題は、クラス変数を最適化することも可能ですか?

たとえば、変数が "内側"の場合、カウント== falseの場合、完全に役に立たず、そこにいる必要はありません。テンプレートパラメータ固有のクラス変数を持つことはできますか?

+0

'counting == false'のテンプレート特殊化を定義しますか? – songyuanyao

答えて

0

メンバーは、未使用の場合でも、別のアドレスを持っています。また、コンパイラはそれを削除しません。しかし、簡単なトリックがあります:空の基地は自分のアドレスを取得する必要はありません。それが専門化と組み合わされていると、どんなデータも取り除くことができます。たとえば:

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. 
}; 

より一般的なconditional_atomic<...>を作成することは可能であろうが、それは使用されている1識別するために、余分なタグの種類を取り、それはもう少し迷惑使用するようになり、必要であろう。しかし、全体的なアプローチは、変数にアクセスするための適切な機能を備えたベースにロジックを置き、何もしないだけの特殊化を提供することです。

関連する問題