Возможно ли реализовать lock free map в C++

мы разрабатываем сетевое приложение на основе C / S, мы обнаруживаем, что слишком много блокировок добавляют к std::map, что производительность сервера стала плохой.

интересно, можно ли реализовать карту без блокировки, если да, то как? Там есть открытый исходный код?

изменить: На самом деле мы используем std::map для хранения информации о сокетах, мы сделали инкапсуляцию на основе описания файла сокета, чтобы включить некоторую другую необходимую информацию, такую как ip-адрес, порт, тип сокета, tcp или udp и т. д.

к резюме, у нас есть глобальная карта, говорят, что это

map<int fileDescriptor, socketInfor*> SocketsMap, 

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

чтобы избежать проблемы уровня параллелизма, у нас есть два решения: 1. хранить каждый socketInfor * отдельно 2. используйте какую-то карту без блокировки.

Я хотел бы найти какую-то карту без блокировки, потому что изменения кодов, требуемые этим решением, намного меньше, чем у решения 1.

6 ответов


на самом деле есть способ, хотя я сам его не реализовал, есть статья о бесплатная блокировка карты с помощью указателей опасности от именитого эксперта C++ Андрея Александреску.


Да, я реализовал Lock-Free Неупорядоченная Карта (docs) В C++, используя концепцию "разделенных упорядоченных списков". Это автоматически расширяющийся контейнер и поддерживает миллионы элементов на 64-разрядном CAS без проблем ABA. Производительность-мудрый, это зверь (см. стр. 5). Это было тщательно протестированы с миллионами случайных операций.


HashMap подойдет? Взгляните на Intel Threading Строительные Блоки, у них есть интересная параллельная карта. Я не уверен, что он свободен от блокировки, но, надеюсь, вас интересует хорошая многопоточность, а не особенно свобода от блокировки. Также вы можете проверить CityHash lib

EDIT:

на самом деле хэш-карте ТББ-это не блокировка-Free


Если вы используете C++11, вы можете посмотреть на AtomicHashMap facebook / folly


вы можете осуществить карту, используя оптимистичный дизайн или транзакций.

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

однако время от времени-столкновение произойдет, и вам придется как-то его привести (обычно путем прокатки вернуться к последнему стабильному состоянию и повторить операцию).

Если ваше оборудование поддерживает достаточно хорошие атомарные операции - это можно легко сделать с сравнить и поменять местами (CAS) - где вы меняете только ссылку (и всякий раз, когда вы меняете карту, вы работаете с копией карты, а не с оригиналом, и устанавливаете ее в качестве основной только при фиксации).


Я удивлен, что никто не упомянул об этом, но Click Cliff реализовал wait-free hashmap в Java, который, я считаю, может быть портирован на C++,