2013-10-03 3 views
2

В конце http://blog.memsql.com/common-pitfalls-in-writing-lock-free-algorithms/ Дэвид Столп показывает данные о производительности для стека блокировки, показывающие, что версия без блокировки медленнее, чем последовательная версия, защищенная мьютексом, даже если конфликт увеличивается. Результаты интересны, но меня интересуют две вещи:Являются ли данные о производительности для стека без блокировки на http://tinyurl.com/pzpyvb9 реалистичным?

  • В лучшем случае «общая пропускная способность» уменьшается, а затем выравнивается по мере увеличения количества потоков. Должна ли общая пропускная способность увеличиваться по мере увеличения количества потоков?
  • В итоговой таблице значения производительности для 1 потока варьируются от 35М до 55М. Это похоже на ужасно широкий диапазон для 1 потока (где не может быть никаких разногласий).

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

+0

Как я вижу, версия мьютекса si самая медленная. –

+0

@GJ: Из того, что я могу сказать, версия на основе мьютекса - это, по сути, та же самая (медленная) скорость, что и «наивная» версия без блокировки (за финальную диаграмму). Это может быть немного медленнее, однако вы правы. Но это не влияет на мои вопросы о пропускной способности, поскольку количество потоков увеличивается или широкий диапазон значений пропускной способности для одного потока. – KnowItAllWannabe

ответ

1

В лучшем случае «общая пропускная способность» уменьшается, а затем выравнивается по мере увеличения количества потоков . Не должна ли общая пропускная способность увеличиваться как Число потоков увеличивается?

Это нормально! Стек - только один! Узкое место - это синхронизация памяти между потоками, а не выполнение кода. Так что, если больше потоков заполняет стек, тогда больше конфликтов памяти должно heppend (условия гонки возникают), поэтому пропускная способность уменьшается.

В итоговой таблице значения производительности для 1 диапазона резьбы от от 35 до 55 м. Это похоже на ужасно широкий диапазон для 1 потока (где не может быть никаких споров).

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

Если вы проверить код, чем вы можете увидеть, что версия SpinLock очень проста и может быть быстрее, чем LockFree, потому что сделано с test_and_set атомной функцией, которая нормально быстрее, чем атомное CAS (сравните и своп), которая используется в LockFree версия.

РЕДАКТИРОВАТЬ:

В LockFree версии используется cmpxchg16b, которая составляет 16 байт CAS в SpinLock используется только 8 байт функции test_and_set (реализованный с cmpxchg8b), поэтому разница в скорости существует!

+0

Если тестовый код выполнил некоторую работу между операциями стека (например, выполните некоторую работу по подготовке объекта к стеку, а затем нажмите его, после того, как вы пометили элемент, выполните некоторую работу над ним), мы ожидаем, что пропускная способность будет увеличиваться по мере того, как количество потоков увеличилось, не так ли? Кроме того, могу ли я исправить то, что вы загрузили контрольный код и посмотрели на него? – KnowItAllWannabe

+0

@KnowItAllWannabe: Проверить код, как стековый безопасный пакет программ для LockFree и SpinLock. В версии LockFree используется 'cmpxchg16b', который имеет 16 байт CAS на SpinLock, используется только 8 байтов CAS cmpxchg8b, поэтому разница в скорости существует! –

+0

Я отмечаю это как принятый ответ, потому что он пришел первым. Ответ Дэвида Хаммена ниже, по сути, тот же, хотя его легче читать. – KnowItAllWannabe

1

В лучшем случае «общая пропускная способность» уменьшается, а затем выравнивается по мере увеличения количества потоков. Должна ли общая пропускная способность увеличиваться по мере увеличения количества потоков?

Не обязательно, и определенно не в этом случае. Многопоточность полезно, если потоки выполнения могут выполняться одновременно. Лучше сделать приложение однопоточным, если потоки никогда не будут выполняться одновременно или если почти все исполнение связано с конфликтом для одного ресурса.

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

В итоговой таблице значения производительности для 1 потока варьируются от 35 до 55 м. Это похоже на ужасно широкий диапазон для 1 потока (где не может быть никаких разногласий).

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