Представьте, что я хочу, чтобы один основной поток и вспомогательный поток выполнялись как два гиперпотока на одном и том же физическом ядре (возможно, заставляя их сродство приблизительно обеспечивать это).
Основной поток будет выполнять важную работу IPC, связанную с ЦП. Вспомогательный поток не должен ничего, кроме как периодически обновлять общее значение временной метки, которое будет периодически читать основной поток. Частота обновления настраивается, но может достигать 100 МГц или более. Такие быстрые обновления более или менее исключают подход, основанный на спячке, поскольку блокировка сна слишком медленная, чтобы спать/просыпаться в течение 10 наносекунд (100 МГц).
Итак, я хочу оживленное ожидание. Тем не менее, ожидание ожидания должно быть максимально дружественным к основному потоку: используйте как можно меньше ресурсов выполнения и, таким образом, добавьте как можно меньше накладных расходов в основной поток.
Я предполагаю, что эта идея будет командой с длинной задержкой, которая не использует много ресурсов, например pause
, а также имеет фиксированную и известную задержку. Это позволило бы нам откалибровать период "сна", поэтому никакое считывание часов даже не требуется (если вы хотите обновить с периодом P
, мы просто выдаем P/L
этих инструкций для откалиброванного занятого сна. Well pause
удовлетворяют этому последнему критерию, так как его латентность сильно варьируется 1.
Второй вариант заключается в использовании команды с длинной задержкой, даже если время ожидания неизвестно, и после каждой инструкции выполните rdtsc
или какой-либо другой метод чтения часов (clock_gettime
и т.д.), чтобы увидеть, как долго мы на самом деле спала. Похоже, что это может сильно замедлить основной поток.
Любые лучшие варианты?
1 Также pause
имеет некоторую специфическую семантику вокруг предотвращения доступа к спекулятивной памяти, которая может или не может быть полезной для этого сценария нисходящего потока, так как я не нахожусь в цикле спина-ожидания.