2014-07-01 2 views
0

У нас есть большой цикл, который нужно вызвать эту функцию-член повторно. Ожидается, что на каждой итерации цикла время вычисления должно быть схожим. Но в наших расчетах он становится намного медленнее, когда число итераций увеличивается. Мы обнаружили, что это вызвано этой функцией-членом. Я не совсем понимаю, почему это происходит. Может ли кто-нибудь объяснить это мне? или какие-либо предложения для такого расчета суммирования для векторов?Проблемы с многократным вызовом функции-члена, в которой реализовано суммирование векторов

Базовая реализация этой части кода:

Dataunit класс, определяющий структуру данных, в которой несколько векторов декларируются и определяются в своих функций членов.

Предсказать - указатель объекта, определенный в классе Residue, которому присвоено значение, использующее здесь. В принципе, перед вызовом функции respdef(), данные, которые Y указывает на, вычисляются, и его указатель может быть вызван вызовом dataOutput(). Также numExp и numResp являются переменными-членами Residue, которые оцениваются в конструкторе при определении.

На каждом шаге эта функция будет вызываться для формирования Yt в соответствии со значениями Y. Например, если цикл равен 10000 шагов, эта функция будет называться 10000 раз. Ожидается, что размер Yt немного изменится, что основано на какуляции набора данных Y. Но этот размер не сильно изменился.

int Residue::respdef() 
{ 
    int m,i; 
    Dataunit tem; //defining a objective of class Dataunit 
    const Dataunit* Y=predict->dataOutput(); //dataOutput() returns a pointer 
    //Size of Yt is set to zero and redefined using push_back and initialization 
    Yt.clear(); 
    for(m=0;m!=numExp;m++) 
    { 
     Yt.push_back(tem); 
     //initialization is a function to define and initialize Yt. 
     Yt[m].initialization(Y[m].tvector.size(),numResp);  
     for (i=0;i!=Y[m].tvector.size();i++) 
     { 
     Yt[m].tvector[i]=Y[m].tvector[i]; //Copying Y[m].tvector to Yt[m].tvector 
     Yt[m].Tvector[i]=Y[m].tvector[i];//Copying Y[m].Tvector to Yt[m].Tvector 
     Yt[m].resp[0][i]=Y[m].resp[0][i]; 
     Yt[m].resp[1][i]=Y[m].resp[0][i]+Y[m].resp[1][i]; 
     Yt[m].resp[2][i]=Y[m].resp[0][i]+Y[m].resp[1][i]+Y[m].resp[2][i]; 
     Yt[m].resp[3][i]=2*Y[m].resp[4][i]; 
     } 
    } 
    return 1; 
} 

Спасибо, что помог мне здесь. Проблема не в этой части кода. Я просто понимаю, что я изменил функцию для вычисления данных Y, добавив push_back, чтобы предотвратить неполные данные. Таким образом, размер Y увеличивается в каждом цикле, что приводит к увеличению размера Yt здесь. Мне нужно изменить размер Y на каждом шагу. Спасибо

+0

Просто удалите весь код, кроме 'return 1;', потому что это всегда результат? :) –

ответ

-1

Ну, это может быть много чего. Это действительно паршивый код, который требует много очистки. Откуда «предсказать», и откуда? Являются ли они переменными-членами или глобальными? Как насчет numExp и numResp? Являются ли они константами, переменными-членами или глобальными? Поскольку код довольно плохо написан и не очень описателен, трудно сделать это из небольшого фрагмента. Там могут быть все виды сумасшедшей перегрузки операторов, что приводит к росту векторов и т. Д. Также неясно, какие другие внешние факторы могут быть задействованы.

Лучшим вариантом будет использование профилировщика для начала. Если у вас этого нет, вы можете установить некоторые точки останова с подсчетом хитов и посмотреть на векторы и посмотреть, растут ли они по последующим вызовам. Наконец, вы можете добавить некоторый подсчет циклов и журнала, чтобы в конце увидеть, число циклов резко увеличивается с течением времени. Если и numExp, и Y [m] .tvector.size() продолжают увеличиваться, время, затраченное на этот метод, будет быстро ухудшаться.

+0

Спасибо Мэтт. Я спешу опубликовать это, поэтому я не сделал это очень ясно раньше. На этот раз я добавлю несколько иллюстраций. Надеюсь, кто-то может рассказать мне об этом. Другие части кода можно запускать плавно, которые мы тестировали в других случаях. Но добавив эту функцию, вычисление становится медленнее и медленнее, когда число итераций увеличивается. Мы не изменили другой код, поэтому, я думаю, именно эта причина вызывает проблему. Прежде чем отправлять это сообщение, я также использую valgrind для обнаружения утечки памяти, но мы не нашли ее. – Albert

1

Это, скорее всего, вызвано вызовом push_back на безоговорочном vector. std::vector хранит все свои объекты в смежной памяти на куче. Он начинается с резервирования памяти (обычно с полномочиями 2) в зависимости от первоначальной потребности и продолжения перераспределения при необходимости. Тем не менее, нет никакой возможности попросить кучу переместить скваттеров, сидящих прямо там, где заканчивается текущее выделение памяти vector, и назначить вам вместо этого. Вместо этого vector запрашивает кучу на сумму, которая больше равна новому желаемому размеру и перемещается (если возможно, копирует в противном случае) все его базовые объекты из старого местоположения в новое. Таким образом, начиная с пустого вектора, время, затраченное на его заполнение объектами n, не является линейным в n. Если у вас есть представление о том, насколько велик ваш вектор, вы можете помочь компилятору и позвонить std::vector::reserve. Это поможет свести к минимуму количество перераспределений и уменьшить связанные с этим накладные расходы.

+0

Спасибо, что ответили на мой вопрос. То, что вы сказали, правильно, и я знаю об этом. Здесь Yt изначально определяется и инициализируется в конструкторе. Кроме того, размер Yt переопределяется с помощью clear(), так что размер Yt не будет постепенно увеличиваться с помощью push_back. Это заставляет меня удвоить ситуацию, о которой вы сказали, здесь не будет. Но я думаю, что использование резерва - хорошая идея предотвратить перераспределение или перемещение вектора в некоторых других случаях. – Albert

+0

Существует разница между размером и емкостью вектора. Несмотря на зависимость от реализации, емкость обычно не уменьшается. Таким образом, вызов 'clear()' сбрасывает размер, но не освобождает память. Это не обязательно плохо. Во-первых, он гарантирует, что в следующий раз, чтобы начать нажимать элементы на этот вектор, у вас нет перераспределения, пока предыдущая емкость не была превышена. Тем не менее, как правило большого пальца, всегда используйте 'reserve'. – Pradhan

+0

Спасибо. Я согласен с использованием резервной копии в коде при изменении размера вектора. – Albert

Смежные вопросы