Почему присвоение переменной стоит так много времени в моем алгоритме итерации значения? - PullRequest
0 голосов
/ 11 октября 2019

У меня есть подпрограмма, опубликованная ниже с результатами профилирования в виде комментариев. Рутина вызывается несколько тысяч раз. 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;
 }

(Не уверен, если это важно: код находит функцию значения a (очень разреженную)Марковский процесс вознаграждения повторяющейся итерацией значения, который выполняется путем вычисления V_ {t + 1} (s) = \ sum_ {s 'в S} P (s, s') V (s). P (s, s ')очень разреженный, поэтому я держу список указателей на состояния, в которые s может переходить для каждого s (sw.transitstostates [событие].)

Я хочу лучше понять, почему определенные вещи являются определеннымиЭто стоит времени. Меня особенно беспокоит тот факт, что первое простое назначение занимает 43% времени, даже если там не делается ни одного вычисления. В этом свете я также удивлен, что первое назначение s.newval (к s.CostsInState) не занимает никакого времени в соответствии с профилировщиком (очень сонный). Поэтому мой вопрос заключается в том, почему эти вещи такие, какие они есть. Правильно ли я могу заключить, что тот факт, что первое назначение во втором цикле, вероятно,артифакт профилировщика? Что заставляет простое присваивание быть таким медленным по сравнению с реальными вычислениями и даже внутренним циклом? Можно ли с этим что-нибудь сделать?

(Кажется, что можно реорганизовать код так, чтобы я сделал две итерации, где роли oldval и newval переключаются, чтобы избежать этого скачка скорости. Но кодбудет значительно менее читабельным, поэтому я лучше сначала пойму, что здесь происходит.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...