Я написал пул потоков с таким количеством потоков, сколько у меня есть (запасные ядра), чтобы избежать переключения контекста. Всякий раз, когда необходимо выполнить новую задачу, эта задача добавляется в незаблокированный кольцевой буфер для использования потоками пула потоков. Каждый раз, когда добавляется новая задача, я сейчас вызываю sem_post.
Мои тесты показывают, что вызов sem_post
занимает 10 микросекунд, когда есть потоки, ожидающие семафора. Некоторые вызовы занимают всего 50 нс (что, вероятно, означает, что полностью в пользовательском пространстве можно было установить, что нет потоков, которые можно было бы разбудить), но также часто встречается значение 350 +/- 30 наносекунд.
Этот вопрос касается случая, когда один или несколько потоков не имеют/не имеют ничего общего и ожидают на семафоре.
Меня совсем не радует, что в этом случае вызывающая сторона (которая пытается разбудить новый поток) тратит 10 микросекунд в sem_post
.
Нет ли более быстрого (с точки зрения вызывающего) способа разбудить спящий поток? Я могу жить с задержкой в 10 микросекунд, пока этот новый поток, наконец, не начнет работать, но поток, который пробуждается, не должен задерживаться так сильно.
Связанные вопросы, которые я мог найти (но не отвечая на мой вопрос):
- Пропускная способность Futex в Linux
- самый быстрый способ разбудить поток без использования условной переменной
Обратите внимание, что семафор, похоже, реализован поверх фьютекса. Я думаю, что фьютекс - самый быстрый способ в Linux? Возможно, быстрее использовать сигнал или прерывание?
sem_post
(полагаю, вы уже просмотрели исходный код для него, учитывая, что он использует фьютекс). Если это слишком медленно для вас, вы всегда можете сделать уведомление в пользовательском пространстве для выделенного потока, который будет запускатьsem_post
s (или все, что необходимо) для вас (при условии, что у вас не так много, что он не может хранить вместе с ними). - person Acorn   schedule 23.09.2019