1

概要: 通常のパターンを持つ一部の C++ コードをリファクタリングして、更新と保守を容易にすることができるかどうかを確認しようとしています。

詳細

プログラムの実行中に統計を追跡するために、スレッド ローカル カウンターを作成するコードがいくつかあります。現在、ソース コードに統計を追加する場合、5 つの更新が必要です。カウンター スレッド ローカル宣言、カウンター合計宣言、スレッド カウンターをリセットする関数、スレッド カウンターを合計に追加する関数、そして印刷機能。

コードは次のようなものです。

// Adding a statistic named 'counter'

// Declaration of counter
__thread int counter = 0;
int total_counter = 0;

// In reset function
counter = 0;

// In add function
total_counter += counter;

// In print function
printf("counter value is: %d\n", total_counter);

次のようなカウンターの宣言用のマクロを作成する方法を確認できます。

#define STAT(name) __thread int name; \
                   int total_##name;

addしかし、これを拡張してandreset関数も更新する方法については考えていませんでした。STAT(counter)理想的には、次のように入力して、統計を管理するためのすべての宣言と関数を処理したいと考えています。

編集

コード内の統計を更新するためのマクロが既にあります。STAT_INC(counter)何かがローカルカウンター値をインクリメントするようなもの。次に、スレッドが実行を終了すると、そのスレッド ローカル値が全体の合計に追加されます。したがって、各統計の名前は重要であるため、配列がうまく機能しないのはそのためです。実際のカウンター名はcache_hitより意味のあるものでcounter[2]あり、作成される統計に任意の名前を付ける機能を失いたくないからです。可能であれば、統計を宣言するときに記述しなければならないコードの量を単純化するためです。

4

3 に答える 3

1

(7分経っても誰も返事をくれませんでした...プレゼントを受け取りました!)

したがって、基本的に、5 つの個別の名前付き変数は必要ありません。配列またはベクトルを使用できます。

int counters[5];

次に、特定のカウンターを更新するのは非常に簡単です。

class Counter {
    int counters[5];
    void update_nth(int n)
    {
        counters[n]++;
    }
};

他のすべての変数についても同様です。

于 2013-05-09T19:03:48.780 に答える
1

H2CO3 の回答に続いて、次のような一般的なイディオムがあります。

enum CounterEnums {
    MyFirstCounter,
    MySecondCounter,
    // ... add new counter names here ...
    NumCounters
};
class Counter {
    int counters[NumCounters];
public:
    void update(int n) { counters[n]++; }
};

これで、別のカウンターを簡単に追加できます。前に NumCounters置くだけです。これで、次のようにインスタンスを宣言できます。

Counter totals; // global
boost::thread_specific_pointer<Counter> counters; // per-thread

と使用

counters->update(MyFirstCounter);

(スレッドごとのカウンターを更新してゼロにする何らかの方法も必要にtotalsなりますが、それは読者の演習として残します)。

于 2013-05-09T19:18:58.190 に答える