Если мой процессор рассчитан на 2 ГГц и имеет 4 ядра с поддержкой 8 потоков, все ли 8 потоков работают с номинальной тактовой частотой? Или они работают на частоте 1 ГГц, поскольку потоков в два раза больше, чем ядер?
2 ответа
Во-первых, ядра не имеют "потоков". Поток - это свойство процесса. Процессы и потоки - это вещи, которые создает операционная система, и процессор действительно не имеет о них прямого представления. Рекламодатели, которые утверждают, что их продукт имеет "четыре ядра и восемь потоков", используют вводящую в заблуждение терминологию.
Ваши ядра имеют один или два логических процессора. Что касается ОС, то логический процессор (LP) может выполнять поток. У вас один LP на ядро, если вы отключили гиперпоточность в настройках прошивки или если ваш процессор не поддерживает HT. Два LP на ядро, если он поддерживает HT. (Будущие процессоры x86/x64 могут реализовать более двух LP на ядро.)
Процессы в типичной системе Windows могут иметь в совокупности от сотен до тысяч потоков в любой момент времени. Количество потоков в каждом процессе можно увидеть на вкладке "Сведения" диспетчера задач (называемой вкладкой "Процессы" в Windows 7 и более ранних версиях) - просто включите столбец "Потоки".
Подавляющее большинство потоков в большинстве систем Windows большую часть времени "ждут" чего-то: они ждут завершения операций ввода-вывода, они ждут истечения таймеров, они ждут ошибки страницы, чтобы быть решенным. Потоки, которые ждут - Unix и Linux используют термин "заблокированный" - не пытаются использовать процессорное время и не используют его, пока не произойдет то, чего они ждут.
Большинство потоков, которые не ждут, либо "работают", что означает, что они на самом деле выполняются на логическом процессоре, либо "готовы", что означает, что они будут работать, но в настоящий момент все LP заняты другими потоками. (Помимо Ready, Running и Wait, есть еще несколько состояний, которые здесь не интересны.)
Все, что следует, касается только "запущенных" потоков.
Если у вас не включен HT, или если у вас включен HT, но количество потоков, которые не ожидают, не превышает количество ядер, то производительность должна быть такой же, как и отключенная HT. Большинство современных операционных систем, включая Windows, пытаются использовать только один LP на ядро, пока не будет больше работающих потоков, чем LP. (Обычно) не имеет смысла помещать два потока в LP одного ядра, оставляя оба LP в другом бездействующем. Операционные системы не всегда успешны на 100%, но в большинстве случаев они работают довольно хорошо.
Если два LP в ядре являются работающими потоками, то сумма "вычислительной" работы, выполненной двумя потоками, вероятно, будет несколько больше ... обычно на 40-60% ... чем если бы у вас было только одно ядро, которое ОС разделяла время между двумя потоками. И общая проделанная работа почти наверняка будет несколько меньше, чем если бы каждый поток работал на ядре сам по себе.
Обратите внимание, что поток, который работает (насколько знает ОС), тем не менее, может быть остановлен в своем LP. Распространенным случаем является случай, когда поток получил доступ к ОЗУ, которого еще нет в кэше L1 ЦП. Требуется время, чтобы перенести необходимые данные из кэша внешнего уровня или из ОЗУ в кэш L1. В течение этого времени поток может не прогрессировать в своем потоке инструкций, но Windows этого не знает. Микропрограмма процессора может использовать это время для выполнения некоторой работы в другом LP в ядре. Или это может сделать некоторую неупорядоченную работу для потока, который ожидает содержимого оперативной памяти. ОС блаженно не знает о таких вещах, просто сообщает о потоке как о "работающем" и продолжает накапливать свое "использованное время ЦП", даже если во время "остановки" она не продвигается вперед.
Итак ... мы можем запускать два потока одновременно через Hyperthreading, по одному на каждый LP в ядре. Но это не означает, что каждое ядро теперь имеет вычислительные ресурсы на два ядра ("исполнительные единицы"), а также не означает, что тактовая частота делится между двумя LP.
Гиперпоточность использует тот факт, что большинство потоков не полностью используют все исполнительные блоки ядра все время. На самом деле, такая ситуация довольно редкая ... И именно поэтому HT может делать то же, что и он. HT позволяет второму потоку сосуществовать в процессоре одновременно с первым, и в идеале этот второй поток может использовать исполнительные блоки, а первый - нет. Это реализовано в микрокоде процессора.
На самом деле в микропрограмме ЦП нет различий между "первым" и "вторым" потоками; он не хочет уделять больше внимания, чем другому. Микропрограмма просто пытается сохранить как можно больше занятых исполнительных блоков ЦП, выполняя как можно больше работы. Гиперпоточность просто дает ему два потока инструкций для работы одновременно, тем самым используя большее количество исполнительных блоков ЦП чаще.
Микропрограмма процессора даже не знает, что операционная система рассматривает как потоки или вообще не "переключение контекста потока". Он просто знает, что имеет два разных потока команд для работы, каждый из которых имеет свой собственный набор значений для указателя инструкций, указателя стека и многих других архитектурных регистров. И иногда, по неизвестным прошивке причинам, ОС приходит и изменяет все это (переключение контекста потока).
Еще одна вещь, которую HT не делает, это реализует какую-либо часть понятия приоритета потоков в ОС. Таким образом, если у вас есть два потока в LP одного ядра HT, и ОС считает, что эти потоки имеют разные приоритеты, прошивка HT в CPU не будет знать об этом. В частности, он не будет назначать исполнительные блоки преимущественно потоку с более высоким приоритетом. ОС использует приоритеты потоков, чтобы решить, какие потоки выбрать для работы на каких процессорах.
Подробнее о том, как работает гиперпоточность, читайте в этой статье на Ars Technica. К сожалению, иллюстрации не появляются, так как они переоснащают свой сайт - возможно, электронное письмо им исправит это. Подробнее о том, как Windows "планирует" потоки, см. Главу "Планирование" в Windows Internals от Solomon, Russinovich, et al.
По сути, ваша операционная система видит количество потоков как количество ядер. Когда один поток не загружен полностью, он использует другой поток чаще, и ваш компьютер работает быстрее. (Я думаю)