HostBoostマルチインデックスコンテナに格納されているクラスのオブジェクトに基づくエージェントベースモデルを高速化するための戦略を探しています。私はSharkを使用して、時間の大部分が関数によって消費されていることを確認しましたcalcSI()。

関数は、クラスの他のインスタンスの属性に依存する特定の確率をcalcSI()クラスのすべてのインスタンスについて計算する必要があります。(のインスタンスは約10,000〜50,000あり、これらの計算はホストごとに約25,600回実行されます。)HostHostHost
プロファイルを正しく解釈している場合、費やされる時間の大部分はに費やされcalcSI()ますHost::isInfectedZ(int)。これは、次のタイプのBoostunordered_multimap内の何かのインスタンスをカウントするだけですInfectionMap。
struct Infection {
public:
explicit Infection( double it, double rt ) : infT( it ), recT( rt ) {}
double infT;
double recT;
};
typedef boost::unordered_multimap< int, Infection > InfectionMap;
のすべてのメンバーはをHost含みInfectionMap carriage、特定のキーに関連付けられてHost::isInfectedZ(int)いる数を単純にカウントします。Infectionsint
int Host::isInfectedZ( int z ) const {
return carriage.count( z );
}
countBoostの順序付けされていないマルチマップの関数のコストに関する情報を見つけるのに苦労しています。Host各キーのインスタンスの数(つまり、各キーにInfections関連付けられている数)を追跡するために、個別の2次元配列に追加してオーバーヘッドを増やす必要がありますintか?1つまたは2つの不要な複合キーインデックスを削除するなど、Boostマルチインデックスの大規模な構造的オーバーホールがより役立つかどうか疑問に思っています。マルチインデックスのバックグラウンドメンテナンスはプロファイラーに表示されないため、(おそらくばかげて)それが大きいのではないかと心配しています。マルチインデックスには8つのインデックスがあり、そのほとんどはordered_non_uniqueです。
プロファイラーに表示されない可能性のある他の懸念事項はありますか、それともプロファイラーからの主要な結果が欠落していますか?
calcSI()残念ながら、の並列化とマルチスレッド化はオプションではありません。
更新:InfectionMap carriage 10ペアを超えることはめったになく、通常は5未満であることを知っておくと役立つ場合があります。
更新2:上記の#1で提案した戦略を試し、それぞれHostに配列int carriageSummary[ INIT_NUM_STYPES ]を指定しました。配列は、の可能な値でインデックス付けされていますz(ほとんどのシミュレーションでは、10未満の可能な値があります)。各エントリの値は、に加えられた変更を追跡しますcarriage。Host::isInfectedZ( int z )関数は次
のようになります。
int Host::isInfectedZ( int z ) const {
//return carriage.count( z );
return carriageSummary[ z ];
}
そして、この関数に費やされる時間は大幅に短縮されたようです。現時点では正確な比較はできません。
明らかに、配列の使用はややかさばりますが、範囲が狭い場合は問題ありませんz。他のコンテナ(つまり、unordered_mapではない)は、より広い範囲でより効率的でしょうか?
マルチインデックスの変更に関するフィードバックもお待ちしています。