首页 > 解决方案 > 为什么在我的值迭代算法中变量赋值要花费这么多时间?

问题描述

我有一个例程,在下面发布了分析结果作为评论。该例程被调用了几千次。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++performanceprofiling

解决方案


推荐阅读