Производительность std :: pow - кеш отсутствует? - PullRequest
7 голосов
/ 20 марта 2010

Я пытался оптимизировать числовую программу и столкнулся с чем-то загадочным. Я зациклен на коде, который выполняет тысячи операций с плавающей запятой, из которых 1 вызов pow - тем не менее, этот вызов занимает 5% времени ... Это не обязательно критическая проблема, но это странно, поэтому я ' Я хотел бы понять, что происходит.

Когда я профилировал сообщения об ошибках кэша, профилировщик VS.NET 2010RC сообщает, что практически все ошибки кэша происходят в std::pow ... так ... что с этим? Есть ли более быстрая альтернатива? Я пытался powf, но это только немного быстрее; он все еще ответственен за ненормальное количество кешей.

Почему базовая функция, такая как pow, вызывает ошибки кэширования?

Редактировать: это не управляемый код. /Oi встроенные функции включены, но компилятор может по своему усмотрению игнорировать это. Замена pow(x,y) на exp(y*log(x)) имеет аналогичную производительность - только теперь все пропуски кэша находятся в функции журнала.

Ответы [ 4 ]

2 голосов
/ 21 марта 2010

Можете ли вы дать больше информации о 'x', а также об окружающей среде, в которой оценивается pow?

То, что вы видите, может быть аппаратными предварительными сборщиками на работе. В зависимости от профилировщика распределение «стоимости» различных инструкций по сборке может быть неправильным, оно должно быть еще более частым для команд с большой задержкой, таких как те, которые необходимы для оценки pow.

Кроме того, я бы использовал реальный профилировщик, такой как VTune / PTU, чем тот, который доступен в любой версии Visual Studio.

2 голосов
/ 20 марта 2010

Да .. это медленно.Почему в деталях может попытаться объяснить кто-то еще, кто чувствует себя более уверенно?здесь: http://martin.ankerl.com/2007/10/04/optimized-pow-approximation-for-java-and-c-c/

1 голос
/ 20 марта 2010

Если вы замените std::pow(var) другой функцией, например std::max(var, var), она все равно будет занимать 5%? Вы все еще получаете все ошибки кэша?

Я предполагаю, что нет вовремя и да, в кеше не хватает. Вычисление способностей происходит медленнее, чем многие другие операции (которые вы используете?). Обращение к коду, которого нет в кеше, приведет к потере кеша независимо от того, какая это функция.

1 голос
/ 20 марта 2010

Если ваш код требует значительного сокращения чисел, я не слишком удивлюсь, что std::pow потребляет 5% времени выполнения. Многие числовые операции выполняются очень быстро, поэтому более медленная операция, такая как std::pow, займет больше времени по сравнению с другими уже быстрыми операциями. (Это также объясняет, почему вы не заметили значительного улучшения при переходе на std::powf.)

Промахи в кеше несколько загадочнее, и трудно представить объяснение без дополнительных данных. Одна из возможностей заключается в том, что если ваш другой код настолько интенсивен в памяти, что он сожирает весь выделенный кеш, то неудивительно, что std::pow принимает все удары по пропускам кеша.

...