Size: a a a

2020 May 06

RC

Roman Covanyan in Go-go!
Daniel Podolsky
это я мог бы даже написать :)

я не понимаю, кому и зачем понадобился такой тип данных в стандартной библиотеке
про это тоже была статья от авторов
источник

а

а кто это in Go-go!
Daniel Podolsky
это я мог бы даже написать :)

я не понимаю, кому и зачем понадобился такой тип данных в стандартной библиотеке
чтоб каждый не писал свое
источник

RC

Roman Covanyan in Go-go!
они решали задачу с ускорением этой конструкции (map + mutex) за счет кэша процессора, кажется. на мьютексе он сбрасывется.
источник

RC

Roman Covanyan in Go-go!
могу соврать
источник

DP

Daniel Podolsky in Go-go!
не, все так
источник

SN

Stanislav N. in Go-go!
Roman Covanyan
она как раз для высоконагруженных. там где-то статья с замерами валялась, на большом числе конкурентных операций sync.Map выигрывает у map+mutex
На большом количестве процессоров, чтобы между кешами не перекидывать все, не?
источник

RC

Roman Covanyan in Go-go!
Stanislav N.
На большом количестве процессоров, чтобы между кешами не перекидывать все, не?
похоже да
источник

АП

Александр Попов... in Go-go!
Если посмотреть на код sync.RWMutex, то можно увидеть, что при блокировке на чтение, каждая горутина должна обновить поле readerCount — простой счётчик. Это делается атомарно с помощью функции из пакета sync/atomic atomic.AddInt32(). Эти функции оптимизированы под архитектуру конкретного процессора и реализованы на ассемблере.


Когда каждое ядро процессора обновляет счётчик, оно сбрасывает кеш для этого адреса в памяти для всех остальных ядер и объявляет, что владеет актуальным значением для этого адреса. Следующее ядро, прежде чем обновить счётчик, должно сначала вычитать это значение из кеша другого ядра.


На современном железе передача между L2 кешем занимает что-то около 40 наносекунд. Это немного, но когда много ядер одновременно пытаются обновить счётчик, каждое из них становится в очередь и ждёт эту инвалидацию и вычитывание из кеша. Операция, которая должна укладываться в константное время внезапно становится O(N) по количеству ядер. Эта проблема называется cache contention.

я как понял они эту проблему зарешали
источник

DP

Daniel Podolsky in Go-go!
в общем, моя рекомендация звучит так: забудьте про sync.Map, ничего полезного в нем для вас нет. если он вам понадобится - вы увидите это в профайлере
источник

АП

Александр Попов... in Go-go!
Daniel Podolsky
в общем, моя рекомендация звучит так: забудьте про sync.Map, ничего полезного в нем для вас нет. если он вам понадобится - вы увидите это в профайлере
ну еще можно его заюзать если нужна конкурентность, но писать свою обвязку с мютекстами лениво
источник

DP

Daniel Podolsky in Go-go!
Александр Попов
ну еще можно его заюзать если нужна конкурентность, но писать свою обвязку с мютекстами лениво
чушь
источник

DP

Daniel Podolsky in Go-go!
я, кстати, скорее имплементирую свой вариант, с раскидыванием по N map+mutex, чем возьму sync.Map. sync.Map - это же сраный динамический тип, вокруг него тоже надо строить свою обвязку с кастингом
источник

АП

Александр Попов... in Go-go!
ну никто не спорит
источник

АП

Александр Попов... in Go-go!
а что кстати скажите по поводу произовдительности на большом количестве ядер?
источник

АП

Александр Попов... in Go-go!
источник

АП

Александр Попов... in Go-go!
картинка из статьи
источник

DP

Daniel Podolsky in Go-go!
можно запросить у автора методику проверки, да и запилить
источник

zl

ziggy lucid in Go-go!
т.е. становится выгодно от 4 ядер?
источник

АП

Александр Попов... in Go-go!
ну по статьи - так
источник

АП

Александр Попов... in Go-go!
сам не тестил
источник