Добрый день!
В поисках подходящего lock-free контейнера наткнулся на concurent_queue с ограничением размера очереди от Intel TBB. Касательно интерфейса и поведения контейнер всем устраивает. Написал тест: два потока — один постоянно помещает элементы в очередь, а другой непрерывно их оттуда считывает. Все здорово, все работает, но почти в 10 раз медленнее, чем при использовании std::deque, доступ к которой синхронизируется критической секцией... Кто-нить может подсказать в чем дело? ОС Win7, Visual Studio 2008 SP1, компилил под x86.
Здравствуйте, The_GorYnycH, Вы писали:
T_G>Добрый день! T_G>В поисках подходящего lock-free контейнера наткнулся на concurent_queue с ограничением размера очереди от Intel TBB. Касательно интерфейса и поведения контейнер всем устраивает. Написал тест: два потока — один постоянно помещает элементы в очередь, а другой непрерывно их оттуда считывает. Все здорово, все работает, но почти в 10 раз медленнее, чем при использовании std::deque, доступ к которой синхронизируется критической секцией... Кто-нить может подсказать в чем дело? ОС Win7, Visual Studio 2008 SP1, компилил под x86.
как вы реализовали ожидания наличия места для вставки и ожидания наличия элемента?
Здравствуйте, The_GorYnycH, Вы писали:
T_G>Добрый день! T_G>В поисках подходящего lock-free контейнера наткнулся на concurent_queue с ограничением размера очереди от Intel TBB. Касательно интерфейса и поведения контейнер всем устраивает. Написал тест: два потока — один постоянно помещает элементы в очередь, а другой непрерывно их оттуда считывает. Все здорово, все работает, но почти в 10 раз медленнее, чем при использовании std::deque, доступ к которой синхронизируется критической секцией... Кто-нить может подсказать в чем дело? ОС Win7, Visual Studio 2008 SP1, компилил под x86.
Здравствуйте, ilnar, Вы писали:
I>как вы реализовали ожидания наличия места для вставки и ожидания наличия элемента?
Это стандартная фича контейнера тут описано
Сначала я помещал и считывал элементы из очереди вызывая методы push() и pop(). контейнер переводит в состояние ожидания(блокирует) считывающий поток, пока в очереди не появится хотя бы один элемент; при помещении в очередь, пока не появится свободное место, записывающий поток также блокируется(хотя в документации это явно не указано). Так работало приблизительно в 10 раз медленнее, после того, как я заменил эти вызовы на try_push() и try_pop(), скорость работы приблизилась к std::deque, но не превысила ее.
I>как минимум, для выяснений понадобится ваш код.
дык, кода-то кот наплакал два потока, один пишет, другой читает и все дела... Инет не на рабочем месте, в следующий раз код принесу, но смотреть там не на что.
Вы использовали этот контейнер? Меня интересует как раз наибольшая пропускная способность контейнера, я думал, что lock-free контейнеры будут работать быстрее STL с синхронизацией, может посоветуете какой-нить другой? Нужна очередь и hash-map.
Здравствуйте, The_GorYnycH, Вы писали:
T_G>Здравствуйте, ilnar, Вы писали:
I>>как вы реализовали ожидания наличия места для вставки и ожидания наличия элемента? T_G>Это стандартная фича контейнера тут описано T_G>Сначала я помещал и считывал элементы из очереди вызывая методы push() и pop(). контейнер переводит в состояние ожидания(блокирует) считывающий поток, пока в очереди не появится хотя бы один элемент; при помещении в очередь, пока не появится свободное место, записывающий поток также блокируется(хотя в документации это явно не указано). Так работало приблизительно в 10 раз медленнее, после того, как я заменил эти вызовы на try_push() и try_pop(), скорость работы приблизилась к std::deque, но не превысила ее.
вы заменили блокированное ожидание try вариантами, что я и подозревал. Код переключения на ожидание события (есть место или появилось что-то), например, на conditional variables требует своих затрат.
в tbb глянул мельком, в функции internal_pop походу есть такой ожидание.
может, причина в этом, попробуйте в concurrent_queue тоже использовать try варианты pop и push
I>>как минимум, для выяснений понадобится ваш код. T_G>дык, кода-то кот наплакал два потока, один пишет, другой читает и все дела... Инет не на рабочем месте, в следующий раз код принесу, но смотреть там не на что.
в том то и дело что тут конкретные байты в тексте решают все))
не понятно что с чем вы сравнили (спрашиваю код не изза лени писать самому)
T_G>Вы использовали этот контейнер? Меня интересует как раз наибольшая пропускная способность контейнера, я думал, что lock-free контейнеры будут работать быстрее STL с синхронизацией, может посоветуете какой-нить другой? Нужна очередь и hash-map.
я использовал.
в случае с TBB разработчики стремятся сделать реализацию не хуже чем у STL с синхронизацией, и не думаю, что они тут сделали хуже, наверное вы сравниваете не на равных условиях (try варианты)
что касается lock-free, concurrent_queue у TBB в общем случае, как я полагаю, таковым не является
и тестирвать надо и с большим количеством потоков, суть TBB в том чтобы быть масштабируемым на большом числе ядер
Здравствуйте, The_GorYnycH, Вы писали:
T_G>Здравствуйте, ilnar, Вы писали:
T_G>Так работало приблизительно в 10 раз медленнее, после того, как я заменил эти вызовы на try_push() и try_pop(), скорость работы приблизилась к std::deque, но не превысила ее.
а вы попробуйте на большем кол-ве потоков чтения и записи