Пусть есть цепочка: A (что-то там делаем, вычисляем подсетку, регулярки, работа состроками)->B (тоже что-то делаем). Пусть у нас есть многопоточный коррелятор, сделанный без изыска. Пришло событие А, сразу за ним приходит В оба попадают в шаренную память. Поток 1 хочет взять событие и поток 2 тоже. Как потоку 1 сказать потоку 2, чтобы он не трогал А, правильно – блокировкой (мьютексы/симафоры и все такое). Поток 2 ловит блок на А и переходит к В (потеряли время). Теперь поток 1 начал обрабатывает А, а поток 2 событие В. Пусть обработка А имеет большую сложность, чем B. В таком случае нам нужен кто-то третий, который получит ответ от потока 2 и дождется ответа от потока 1. Ура, вот мы потеряли еще время и получили нового участника корреляции, который также жрет память и такты проца.
Усложним задачу. Пусть обработка А требует записи в табличный список, а В чтения того, что записалось ранее. Если время обработки А и В разное, следовательно поток 2 будет вынужден ждать поток 1, т.е. получаем лок. Если у нас таких правил не 1, а сотни, мы впадем в постоянные локи и большую часть времени коррелятор будет ждать их снятия.
Вспомним что входящий поток нельзя уменьшить и вот мы получаем коррелятор, который весь в локах и копит очереди т.к. не справляется. И это я еще не рассматриваю ситуацию дед локов.