Эмпирическое правило для потоков заключается в том, что для каждого «исполнительного блока», доступного на компьютере, требуется по крайней мере один «активный» (способный выполнять свои команды немедленно при заданном времени процессора). «Исполнительный блок» - это один процессор логических команд, поэтому четырехъядерный четырехъядерный гиперпоточный сервер Xeon будет иметь 32 EU (4 микросхемы, 4 ядра на микросхему, каждая гиперзаходная). Ваш средний Core i7 будет иметь 8.
Один поток в ЕС - это наиболее полное использование мощности процессора при условии, что потоки всегда будут в рабочем состоянии; это почти никогда не происходит, поскольку потокам необходим доступ к некешированной памяти, жесткому диску, сетевым портам и т. д., которых они должны ждать, и которые не требуют активного внимания ЦП для выполнения. Таким образом, вы можете еще больше повысить общую эффективность, добавив больше потоков в очередь и рваясь в путь. Это действительно стоит денег; когда ЦП переключает поток, он должен кэшировать регистры потока, указатель выполнения и другую информацию о состоянии, которая обычно хранится во внутренних документах ЕС и очень быстро доступна, что позволяет другим ЕС в этом чипе ЦП забрать его. Также требуется, чтобы потоки в ОС решали, на какой поток следует переключиться. Наконец, когда ЕС переключает темы, он теряет прирост производительности конвейерной обработки, которую использует большинство процессорных архитектур; он должен промыть конвейер перед переключением потоков. Но, поскольку все это в среднем занимает гораздо меньше времени, чем простое ожидание, пока жесткий диск или даже ОЗУ не вернутся с информацией, это стоит затрат.
Тем не менее, как правило, когда вы вдвое превышаете число «активных» потоков по сравнению с ЕС, ОС начинает тратить больше потоков планирования времени ЕС, а ЕС тратит больше времени на переключение между ними, чем фактически тратит на запуск активных потоков. программ. Это точка диссоциации масштаба; на самом деле многопоточный алгоритм будет работать дольше, если в этот момент вы добавите дополнительный поток.
Итак, в целом, вы хотите сохранить как минимум столько потоков в вашей программе, сколько у вас есть EU на компьютере, но вы хотите избежать более чем удвоения этого числа, которое не ждет или не спит.