c++ - 为什么在我的值迭代算法中变量赋值要花费这么多时间?
问题描述
我有一个例程,在下面发布了分析结果作为评论。该例程被调用了几千次。statesVec 包含大约 1000000 个状态。在分析时,我注意到以下几点:
void IterateValues()
{
for (auto& sw : statesVec)
{
sw.oldVal = sw.newval; //43%
}
for (auto& sw : statesVec) //6.5%
{
auto& probs = mrp.EventProbs();
auto NumEvents = probs.size();
sw.newval = sw.CostsInState;//1% !
for (size_t event = 0; event < NumEvents; event++)
{
//Note sw.TransitsToStates is a vector containing
//pointers to elements of statesVec
sw.newval += sw.TransitsToStates[event]->oldVal * probs[event];//49.5%
}
sw.newval*=alpha;
}
}
statesVec 包含状态:
Struct state
{
double newval;
double oldVal;
std::vector<State*> TransitsToStates;
double CostsInState;
}
(不确定这是否重要:代码通过重复值迭代找到(非常稀疏的)马尔可夫奖励过程的值函数。它通过计算 S 中的 V_{t+1}(s)=\sum_{s' 来做到这一点P(s,s') V(s). P(s,s') 非常稀疏,所以我保留了一个指针列表,指向每个 s (sw.transitstostates[event]. )
我想更好地理解为什么某些事情会花费时间。我特别担心第一个简单分配需要 43% 的时间,即使那里没有进行任何计算。鉴于此,我也很惊讶根据分析器(非常困),第一次分配给 s.newval(给 s.CostsInState)并不需要任何时间。所以我的问题是为什么这些事情是这样的。我是否正确推断第二个循环中的第一个分配可能是分析器的工件?与实际计算甚至内部循环相比,是什么导致简单分配如此缓慢?有什么可以做的吗?
(似乎可以重构代码,以便我进行两次迭代,其中 oldval 和 newval 切换角色,以避免这种减速带。但是代码的可读性会大大降低,所以我宁愿先了解这里发生了什么. )
解决方案
推荐阅读
- c# - 如何在 NLog C# 的不同目标中提及不同的时区
- azure-data-factory - ADF 数据流中的 Azure 表存储接收器
- javascript - 在 Next.js + Redux-saga 中刷新窗口时如何设置授权标头?
- flutter - 热重载、热重启和完全重启有什么区别?
- python - Django:使用对象属性过滤查询
- python - 使用 Kubernetes python 客户端列出命名空间中的所有资源
- java - 如何将响应字符串转换为 json 对象
- ruby-on-rails - 实现文件请求计数器
- python - “S3File”对象没有“强制”属性
- ruby-on-rails - 从 Rails 模型调用 Gem 中的方法