Самый быстрый способ разбудить поток пула потоков

Я написал пул потоков с таким количеством потоков, сколько у меня есть (запасные ядра), чтобы избежать переключения контекста. Всякий раз, когда необходимо выполнить новую задачу, эта задача добавляется в незаблокированный кольцевой буфер для использования потоками пула потоков. Каждый раз, когда добавляется новая задача, я сейчас вызываю sem_post.

Мои тесты показывают, что вызов sem_post занимает 10 микросекунд, когда есть потоки, ожидающие семафора. Некоторые вызовы занимают всего 50 нс (что, вероятно, означает, что полностью в пользовательском пространстве можно было установить, что нет потоков, которые можно было бы разбудить), но также часто встречается значение 350 +/- 30 наносекунд.

Этот вопрос касается случая, когда один или несколько потоков не имеют/не имеют ничего общего и ожидают на семафоре.

Меня совсем не радует, что в этом случае вызывающая сторона (которая пытается разбудить новый поток) тратит 10 микросекунд в sem_post.

Нет ли более быстрого (с точки зрения вызывающего) способа разбудить спящий поток? Я могу жить с задержкой в ​​10 микросекунд, пока этот новый поток, наконец, не начнет работать, но поток, который пробуждается, не должен задерживаться так сильно.

Связанные вопросы, которые я мог найти (но не отвечая на мой вопрос):

Обратите внимание, что семафор, похоже, реализован поверх фьютекса. Я думаю, что фьютекс - самый быстрый способ в Linux? Возможно, быстрее использовать сигнал или прерывание?


person Carlo Wood    schedule 23.09.2019    source источник
comment
Что вы подразумеваете под избеганием переключения контекста? Вы привязываете каждый поток к каждому ядру, не позволяя планировщику их перемещать или вынимать, или что вы имеете в виду?   -  person Acorn    schedule 23.09.2019
comment
Что касается таймингов, Linux — это не операционная система реального времени, поэтому все идет так, как они говорят. Тем не менее, я понятия не имею о мягких гарантиях sem_post (полагаю, вы уже просмотрели исходный код для него, учитывая, что он использует фьютекс). Если это слишком медленно для вас, вы всегда можете сделать уведомление в пользовательском пространстве для выделенного потока, который будет запускать sem_posts (или все, что необходимо) для вас (при условии, что у вас не так много, что он не может хранить вместе с ними).   -  person Acorn    schedule 23.09.2019
comment
@Acorn Linux — это не операционная система реального времени, поэтому все идет так, как они говорят. Однако, если вы проявите должную осмотрительность в Linux, вам может вообще не понадобиться операционная система жесткого реального времени.   -  person Maxim Egorushkin    schedule 23.09.2019
comment
10 микросекунд, на каком процессоре? Для процессора с частотой 40 МГц это невероятно быстро (~ 400 циклов), а для процессора с частотой 4 ГГц это не так быстро, но не обязательно плохо, особенно если может потребоваться несколько тысяч циклов только для того, чтобы вывести ранее бездействующий процессор из состояния энергосбережения. .   -  person Brendan    schedule 23.09.2019
comment
@Acron Когда я запускаю больше потоков, чем у меня есть ядер, планировщику придется постоянно переключаться между потоками. Но когда у меня есть одно ядро ​​​​для каждого потока (или, если потоки спят даже больше ядер, чем запущенных потоков), то это не обязательно.   -  person Carlo Wood    schedule 23.09.2019
comment
@Acorn И как мне разбудить эту выделенную ветку? Или вы предполагаете, что этот выделенный поток будет вращаться, наблюдая за какой-то атомарной переменной? Это не вариант; Я бы потерял целое ядро ​​​​с этим ...   -  person Carlo Wood    schedule 23.09.2019
comment
@CarloWood Что касается планирования: да, вы сокращаете количество переключений контекста, но в зависимости от рабочей нагрузки, системных вызовов, других процессов в системе и т. д. у вас все еще может быть много переключений контекста.   -  person Acorn    schedule 23.09.2019
comment
@CarloWood Что касается выделенного потока: да, выделенный поток вращается так быстро, как вам нужно, в поисках изменений памяти / L3. Вы, конечно, потеряете ядро, но получите лучшую задержку, которая кажется вашей проблемой, а не пропускной способностью.   -  person Acorn    schedule 23.09.2019