我正在寻找加速基于代理的模型的策略,该模型基于 class 的对象Host
,指向这些对象的指针存储在 Boost 多索引容器中。我使用 Shark 来确定绝大多数时间都被一个函数消耗calcSI()
:
函数calcSI()
必须为类的每个实例计算Host
某些概率,这些概率取决于类的其他实例的属性Host
。(大约有 10,000-50,000 个实例Host
,并且这些计算为每个主机运行大约 25,600 次。)
如果我正确解释了配置文件,则花费的大部分时间都calcSI()
转到Host::isInfectedZ(int)
,它只是计算类型为 Boost unordered_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
contains的所有成员InfectionMap carriage
,并简单地计算与特定键关联Host::isInfectedZ(int)
的数量:Infections
int
int Host::isInfectedZ( int z ) const {
return carriage.count( z );
}
我无法找到有关
count
Boost 的无序多图的功能成本有多大的信息。我是否应该通过添加到Host
单独的二维数组来跟踪每个键的实例数(即与每个键Infections
关联的数量int
)来增加开销?我想知道对 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)对于更大的范围会更有效吗?
也希望获得有关更改多索引的任何反馈。