При выполнении задачи с интенсивными вычислениями на сервере с четырехъядерным процессором Intel i7 с Hyperthreading, идеально ли выполнять восемь потоков (для восьми виртуальных ядер) или только четыре (для четырех физических ядер)? Каждый поток обеспечивает постоянное 100% использование виртуального ядра.
8 потоков были бы идеальными, если предположить, что нет значительных дополнительных накладных расходов на объединение результатов или что-то в этом роде. При наличии всего четырех потоков любые исполнительные блоки, которые не могут быть насыщены одним потоком на виртуальное ядро, будут потрачены впустую. Их можно использовать с восемью потоками.
Обратите внимание, что это относится только к нереалистичному предположению, что каждый поток может насыщать ядро. Кроме того, это может не применяться, если разделение ресурсов кэша процессора отрицательно сказывается на производительности. Некоторые задачи имеют производительность, которая «падает с обрыва» при определенном размере кэша. Если ваш разрыв находится между полным размером кеша физического ядра и половиной этого размера кеша, то четыре потока могут быть лучше.
Я предполагаю, что оптимально использовать одну задачу на ядро и отключить гиперпоточность.
Если я запущу столько потоков с интенсивным процессором, сколько у меня есть логических ядер, у меня будут быстрые переключатели контекста для задач с интенсивным использованием процессора, но дорогие для фоновых задач, поскольку гиперпоточность полностью потребляется задачами с интенсивным процессором. С другой стороны, если я запущу столько потоков с интенсивным использованием процессора, сколько у меня физических ядер, у меня не будет переключений контекста для этих задач и быстрых переключений контекста для фоновых задач. Вроде бы хорошо, но фоновые задачи найдут свободные логические процессоры и будут запускаться практически мгновенно. Как будто они выступают в реальном времени (хорошо -20).
Я не знаю, насколько быстро происходит переключение контекста между двумя задачами на одном ядре. Также я боюсь, что совместное использование кеша между двумя потоками на одном ядре снизит частоту попаданий в кеш (если только они не запускают одну и ту же программу размером менее 1 МБ). Сомневаюсь, что без штрафных санкций. Мне кажется, что сложная задача с интенсивным использованием ЦП будет выполняться быстрее для одной задачи на ядро, чем одна задача на виртуальный процессор. Но если вы это сделаете, вы оставите два виртуальных процессора свободными, а фоновые задачи получат приоритет, которого у них не должно быть.
В первом сценарии гиперпотоковость используется, фоновые задачи будут использовать дорогостоящие переключатели контекста, потому что я максимизировал гиперпоточность с помощью нормальной обработки. Второй вариант неприемлем, потому что до 50% мощности моего процессора отдается приоритетным фоновым задачам.
Обычно я отключаю гиперпоточность на моем рабочем столе и серверах Intel. Я показываю как в https://serverfault.com/a/720471/309821.
Но это основано на догадках. Мне кажется, что лучше, но может и нет.
Доктрина, которой меня учили при компиляции, была в 1,5 раза больше количества ядер. Это учитывает любое время, когда поток / процесс ожидает ввода-вывода.
Если у вашей задачи нет шансов заблокировать более медленные операции, такие как ввод-вывод, тогда может не быть необходимости превышать количество ядер, но если это возможно, вам понадобится больше процессов, чем ядер.
Посмотрите на это так: если у вас есть четыре ядра и три процесса, вы никогда не сможете достичь 100% ЦП. То же самое верно для четырех процессов, когда один из них блокирует ввод-вывод. Если у вас есть шесть процессов без блокировки, вы можете быть немного менее эффективными, поскольку ядро использует некоторое время ЦП, переключая процессы на четыре ядра и обратно, но ни одно ядро никогда не будет бездействовать.
К сожалению, я понятия не имею о физическом / виртуальном аспекте вашего вопроса.