2012-12-13 2 views
0

После наблюдения некоторых проблем с производительностью в моей программе я решил запустить сеанс профилирования. Результаты, похоже, указывают на то, что примерно 87% взятых проб были как-то связаны с моей функцией Update().вопросы профилирования и производительности

В этой функции я просматриваю список A*, где sizeof(A) равно 72 и удаляет их после обработки.

void Update() 
{ 
//... 

    for(auto i = myList.begin(); i != myList.end(); i++) 
    { 
     A* pA = *i; 
     //Process item before deleting it. 
     delete pA; 
    } 

    myList.clear(); 

//... 
} 

где myList - std::list<A*>. В среднем, я вызываю эту функцию где угодно от 30 до 60 раз в секунду, в то время как список содержит в среднем 5 элементов. Это означает, что я удаляю от 150 до 300 A объектов в секунду.

Вызов удаления этого много раз будет достаточным, чтобы вызвать проблему с производительностью в большинстве случаев? Есть ли способ отслеживать, где именно происходит эта проблема? Действительно ли удаление считается дорогостоящей операцией?

+1

Что делает деструктор 'A'? Есть много вещей, которые могут вызвать «проблемы с производительностью». Например, попробуйте использовать 'std :: vector' вместо' std :: list', только местонахождение кеша может оказать огромное влияние на производительность. – Chad

+0

Я не определил деструктор, только конструктор. Я попробую заменить список вектором и посмотреть, поможет ли он. – user987280

+1

Другая проблема заключается в том, что все эти маленькие объекты 'A' лежат вокруг, особенно при использовании в сочетании со списками (и, возможно, с другими распределениями). Ваша память будет разбита и рассеяна. Возможно, вам захочется подумать о создании специализированного распределителя для выделения этих объектов 'A', выделения и восстановления в непрерывный пул неиспользуемых объектов' A'. –

ответ

1

Очень трудно сказать, так как вы чистите над тем, что, вероятно, большая часть работы, проделанной в петле и не дают ни малейшего намека на то, что А ...

Если A представляет собой простой набор данных, в частности примитивов, то удаление почти наверняка не является виновником. Вы можете проверить теорию, разделив вашу функцию обновления на две части - обновление и uninit. Обновление выполняет всю обработку, uninit удаляет объект и очищает список.

Если обновление выполняется медленно, то это обработка. Если только uninit медленный, то это удаление. Если они медленны, то фрагментация памяти, вероятно, является виновником.

Как указано в комментариях, std :: vector может дать вам увеличение производительности. Но будьте осторожны, так как это может также вызвать проблемы с производительностью в другом месте в зависимости от того, как вы создаете структуру данных.

+0

'A' составлен почти полностью из примитивных типов. Я думаю, что «удалить» может не быть проблемой после прочтения вашего ответа. Благодарим вас за помощь в разделении на разные функции. – user987280

0

Вы можете взглянуть на tcmalloc от gperftools (Инструменты эффективности Google). gperftools также содержит профилировщик (обе библиотеки должны быть связаны, очень просто). tcmalloc хранит пул памяти для небольших объектов и повторно использует эту память, когда это возможно. Профилировщик может использоваться для профилирования процессора и кучи.

0

Полностью легко понять, что происходит.

Сделайте себе одолжение и используйте this method. Он был проанализирован в n-й степени и очень эффективен.

Вкратце, если 87% времени находится в Update, то если вы просто остановите его несколько раз с помощью Ctrl-C или что-то еще, вероятность составляет 87% каждый раз, когда вы поймаете его в действии.

Вы не только увидите, что он находится в Update. Вы увидите , где в Update, и что это делает. Если он находится в процессе delete или обращается к структуре данных, вы увидите это. Вы также увидите, далее по стеку, причина, по которой эта операция требует времени.

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