У меня есть критический путь кода, в котором потоки используют атомное приращение целого числа, чтобы подсчитать количество событий, которые произошли во всем мире. Это достаточно быстро, но по-прежнему требует, чтобы линия кеша, содержащая целое число, отскакивала между ядрами. В системе NUMA это создает много трафика MESI.Атомный, масштабируемый, монотонный счетчик с границей
Псевдо код горячего погладить является то, что все нити этого:
const int CHECK_VALUE = 42;
int counterNew = counter++;
if (counterNew == CHECK_VALUE) {
Do Final work
}
Счетчик монотонно возрастает и значение оно должно достигать заранее известно.
По крайней мере, один поток должен заключить, что глобальный счетчик достиг CHECK_VALUE
после того, как он увеличил counter
. Допустимо, что более одного потока делает этот вывод (я всегда могу синхронизировать их в этой точке, поскольку это уже не горячий путь).
Можно ли сделать лучше, чем использование атомного приращения, чтобы отслеживать значение counter
, если я знаю, что он монотонен и конечное значение известно?
Атомные CAS или спиновые блокировки на самом деле медленнее, чем использование реализации Atom inc. У меня уже есть ... (__sync_fetch_and_add на C) –