nginx-1.2.5

Maxim Dounin mdounin at mdounin.ru
Thu Nov 15 14:19:05 UTC 2012


Hello!

On Thu, Nov 15, 2012 at 01:54:44PM +0400, Anton Yuzhaninov wrote:

> On 11/14/12 21:44, Maxim Dounin wrote:
> >Но, честно говоря, я так подозреваю, что даже цифры выше - это,
> >скорее всего, далеко не просто стоимость инструкций, а результат
> >выбрасывания нужных данных из кеша процессоров из-за обновления
> >счётчика (читай: cache line flush'ился, и route entry при других к
> >ней обращениях приходилось перегружать из памяти).  В этом месте
> >nginx поступает как правильно, и счётчики держит отдельно от
> >всего, да ещё и с отступом в cache line между ними.
> 
> Сама по себе операция изменения счетчика, разумеется очень дешевая.
> Весь эффект, из за необходимости синхронизации кэшей CPU.
> После того, как счетчик инкрементирован он сначала попадает только в
> локальный кэш CPU. Если потом код работающий на другом CPU захочет
> инкрементировать этот же счетчик, он должен будет подождать, пока
> первый CPU запишет эти данные в main memory, и потом прочитть их
> оттуда. Для того, чтобы узнать сосотяние кэша (нужно ли ждать и
> сколько ждать) используются разные протоколы для обеспечения cache
> coherency, но почти все плохо масштабируются с увеличенимем числа
> кэшей. В итоге при достаточно большом числе процессоров и ядер даже
> простой инкремент общего на много CPU счетчика может стать узким
> местом.

Это понятно.  Но я как бы о том, что в конкретном случае route 
entry - скорее всего эффект не от самих изменений, а из-за cache 
trashing других данных в результате этих изменений.  Т.е. из-за 
того, что счётчик находится в той же линии кеша, что и другие 
полезные данные.

Наблюдать contention на обновлении отдельностоящего счётчика - 
куда как сложнее.  Сейчас погонял тесты на своём ноутбуке: tight 
loop обновления счётчика при увеличении количества потоков от 
одного до 4-х (== количество thread'ов в процессоре) становится в 
6 раз медленнее, но и это "медленнее" - это 50 миллионов 
обновлений счётчика в секунду на поток, без всякой оптимизации.

Если тебе вдруг будет не лень повторить тот эксперимент с 
форвардингом, на который ты ссылался, можно попробовать вместо 
того, чтобы убирать обновление счётчика - отодвинуть его в 
отдельный cache line, сделав вокруг него padding в cache line 
size.  Если я правильно понимаю - на выходе должны получиться 
практически те же самые 2 процента, что и просто от его убирания.

> В случае nginx наверно измеримого эффекта не будет - счетчики
> инкрементируются относительно редко, на один http запрос выполняется
> много разной работы.

С этого я и начал. :)

> Но теоретически будет немного быстрее, если каждый воркер будет
> писать в свою облать памяти, а скалдываться все эти счетчики будут
> только для чтения статистики (т. е. относительно редко).

Теоретически - да, а на практике - чтобы заниматься подобными 
оптимизациями, неплохо бы сначала иметь измеримый эффект.

-- 
Maxim Dounin
http://nginx.com/support.html



Подробная информация о списке рассылки nginx-ru