Форум программистов, компьютерный форум, киберфорум
Наши страницы
Evg
Войти
Регистрация
Восстановить пароль
Рейтинг: 5.00. Голосов: 9.

Что такое Hyper-threading "на пальцах"

Запись от Evg размещена 21.01.2014 в 22:56
Обновил(-а) Evg 19.05.2018 в 18:31

1. Предисловие

Многим доводилось при покупке процессора, компьютера, ноутбука или нетбука сталкиваться с вопросом, что означает фраза "1 ядро/2 потока" в характеристиках процессора. По умному отличие количества ядер и количества "потоков" (причём, ровно в два раза) называется словом "hyperthreading". Что это такое - тема довольно избитая и много где объяснённая, но мне неожиданно в голову пришёл жизненный аналог, который показался мне хорошим для объяснения "на пальцах". В данной статье я попытался сделать пояснение для НЕэкспертного читателя, что такое hyperthreading, не вникая в техническое внутреннее устройство процессора

*** UPDATE
Словом "поток" (thread) в программировании обозначают понятие "программный поток". Поток является одной из технологий распараллеливания вычислений (т.е. ассоциируется с ускорением вычислений). В качестве русскоязычных семантических аналогий можно привести фразы "поток воды в реке" или "поток машин на дороге". Маркетологи заиспользовали это же самое слово для описания характеристики процессора. Хочется сразу заострить внимание на том, что "поток" как программный поток и "поток" как маркетинговая характеристика процессора - это две разные сущности, которые, к великому несчастью, обозначаются одним и тем же словом. В дальнейшем повествовании из контекста будет понятно, о котором из "потоков" идёт речь. А по факту в дальнейшем повествовании все маркетинговые "потоки" взяты в кавычки. Я буду пользоваться маркетинговым термином "поток" (взятым в кавычки) исходя из того, что он более привычен для предполагаемой аудитории

В комментариях развернулась довольно длинная дискуссия, которая может оказаться полезной тем, кто хочет поглубже понять природу hyperthreading'а. Тем, кого данная тема интересует только с позиции "покупать или не покупать", читать комментарии большого смысла не имеет, т.к. дискуссия носит технический характер. Но здесь нужно будет учесть, что статья несколько раз дорабатывалась и отдельные куски переписывались. Из-за этого может возникнуть недопонимание некоторых старых комментариев. Начиная с какого-то момента я старался все обновления помечать "*** UPDATE", чтобы проще было увидеть более поздние добавления

*** UPDATE
Более детальное описание я сделал в цикле из четырёх статей, который начинается отсюда: http://www.cyberforum.ru/blogs/18334/blog4913.html. Но этот цикл статей рассчитан на более высокий уровень знаний у читателя

2. Пример "на пальцах"

Есть плотник дядя Вася. У него есть топор, которым он умеет вырезать из поленьев фигурки. Есть заказчики, которые приносят к дяде Васе поленья. Заказчик приходит, даёт полено дяде Васе, дядя Вася некоторое время вырезает топором фигурку, отдаёт заказчику, заказчик уходит. Далее дядя Вася ждёт следующего заказчика. Когда тот приходит, то картина повторяется. При низком потоке заказчиков дядя Вася загружен слабо (то работает, то отдыхает). Заказчиков может быть много. В этом случае как только дядя Вася закончил один заказ, он тут же принимается за другой. При большом потоке заказчиков дядя Вася загружен сильно (постоянно работает).

Но дядя Вася человек, а потому иногда ему приходится бегать в туалет. В тот момент, когда дядя Вася ходит в туалет, топор валяется без дела. Т.е. при 100% загрузке работой дяди Васи, топор загружен менее, чем на 100% из-за вынужденного простоя в моменты, когда дядя Вася находится в туалете.

Когда образовалась большая очередь, то традиционно некоторые заказчики начали считать себя умнее других и лезть без очереди. Со временем даже образовалась очередь из тех, кто лезет без очереди. Таким образом мы имеем две очереди заказчиков и одного дядю Васю, который работает с той же самой скоростью, потому как он по очереди (а не одновременно) берёт полено то из первой очереди, то из второй. Визуально наблюдается некоторая параллельность, потому что уходят в работу поленья то из одной, то из другой очереди (а не так, чтобы сначала обработали все поленья из одной очереди, а потом из другой). Но при этом, несмотря на видимость параллельности, количество фигурок, выпускаемых в единицу времени, равна производительности одного дяди Васи

У дяди Васи есть сын Лёша. Но у него нет своего топора. Поэтому в те моменты, когда дядя Вася ходит в туалет, Лёша берёт топор и обслуживает заказчиков. Как только дядя Вася возвращается из туалета, Лёша отдаёт ему топор и продолжает работать только тогда, когда дядя Вася в очередной раз идёт в туалет. При таком порядке работы топор загружен на 100%, потому что он всегда в руках либо дяди Васи, либо Лёши. Они даже договорились, что дядя Вася обслуживает основную (большую) очередь, а Лёша обслуживает (короткую) очередь для тех, кто без очереди. При таком раскладе количество фигурок, выпускаемых ими двоими в единицу времени больше, чем в случае, когда дядя Вася работал один, и равна производительности дяди Васи плюс небольшой довесок, но ни в коем случае не равна производительности дяди Васи плюс производительность Лёши. Довесок зависит от того, сколько времени проводит дядя Вася в туалете. Если дядя Вася бегает в туалет быстро, то производительность дяди Васи и Лёши чуть-чуть больше, чем производительность одного дяди Васи. Если дядя Вася засиживается в туалете долго, то производительность дяди Васи и Лёши ощутимо больше, чем производительность одного дяди Васи

Но Лёша тоже человек, и ему тоже надо ходить в туалет. В основном походы в туалет дяди Васи и Лёши по времени не пересекаются. Но иногда всё-таки случается, что в туалет им хочется одновременно. В этом случае они играют партию в карты, по результату которой определяется, кто первым зайдёт в туалет. В этом случае топор мало того, что простаивает, а может ещё и простаивать довольно долго. А суммарная производительность дяди Васи и Лёши может оказаться меньше, чем производительность одного дяди Васи из-за того, что неэффективно тратится время на игру в карты

В мастерскую на пять минут в гости заскочил маркетолог дядя Джон. Он повесил рекламный плакат: "Теперь у нас в мастерской в два раза больше плотников, а поэтому мы работаем быстрее". Рекламный плакат выполняет свою роль - он обманывает людей, говоря чистую правду. В мастерской действительно стало в два раза больше плотников, т.к. вместо одного их стало двое. Мастерская действительно увеличила производительность, т.к. при помощи Лёши производительность немного выросла. Но реклама ненавязчиво толкает незнающего человека к ложному выводу, что производительность мастерской увеличилась в два раза. В реальности производительность вырастает только в том случае, если у нас появляется вторая очередь (поскольку есть договор, что Лёша обрабатывает только вторую очередь). Производительность вырастает немного, конкретная величина роста зависит зависит от того, как долго дядя Вася проводит время в туалете. А с учётом того, что дядя Вася и Лёша могут начать играть в карты, производительность может в том числе и уменьшиться.

*** UPDATE
В реальности дело обстоит следующим образом. В мастерской есть исполнительное устройство - топор. Теоретическая производительность мастерской определяется производительностью топора. Если рассмотреть модель сферического дяди Васи в вакууме, то он в состоянии достичь этой теоретической производительности за счёт того, что он вообще не будет бегать в туалет и 100% рабочего времени будет работать топором. Но в реальной жизни всё обстоит не так и реальный дядя Вася всё-таки бегает в туалет, а потому он тратит на работу только условных 90% рабочего времени. Т.е. реальный дядя Вася в одно рыло в состоянии обеспечить мастерской лишь 90% от её теоретически возможной производительности из-за того, что условные 10% времени топор валяется без дела. Наличие второго плотника (Лёша) позволяет довести производительность мастерской до теоретического максимума за счёт того, что топор постоянно будет находиться в работе. При этом важно понимать, что наличие Лёши, строго говоря, не ускоряет работу, а лишь компенсирует негативные явления, обусловленные тем, что в работе дяди Васи возникают неизбежные потери времени

3. Проводим аналогии

*** UPDATE
Хочется обратить внимание на то, что мастерская НЕ является моделью процессора. Процессор устроен намного сложнее. Мастерская является всего лишь простым для восприятия аналогом, на котором можно понять, какой прирост в производительности и в каких случаях даёт hyperthreading

Мастерская, в которой работают дядя Вася и Лёша является аналогом процессорного ядра с hyperthreading'ом ("двухпоточного процессорного ядра" в терминологии маркетологов). Дядя Вася и Лёша являются аналогами двух логических процессоров, которые работают на одном исполняющем устройстве, аналогом которого является топор. Заказчики с поленьями являются аналогом вычислительных задач, не уточняя при этом, чем конкретно (одной машинной операцией, одним процессом, чем-то ещё). Другими словами, заказчики с поленьями - это полезная нагрузка. Очереди заказчиков символизируют собой полезную нагрузку, которую можно выполнять параллельно (независимые процессы/потоки). Но отсутствие очереди не означает, что отсутствует загрузка, которую можно распараллелить. Просто люди в очереди культурные и их устроит, что их заказы будут обрабатываться по очереди. Туалет выполняет роль памяти.

Строго говоря, вместо Лёши было бы более правильно ввести брата дяди Васи дядю Петю, потому что в "двухпоточном" процессоре логические ядра симметричны, а не так, что одно большое, а другое маленькое. Но для удобства я ввёл именно маленького Лёшу (о причинах поясню чуть ниже).

Случай, когда заказчиков мало, соответствует низкой полезной загрузке процессора (отсутствие тяжёлых задач). Как видим, дядя Вася загружен не на 100% и иногда может отдыхать. Наличие или отсутствие Лёши никакой роли не играет (производительность труда не увеличивает). Т.е. при низкой загрузке "двухпоточный" процессор работает с той же производительностью, что и "однопоточный"

Теперь возьмём случай, когда заказчиков много, но они очередь не образуют. И, допустим, в предельном случае всё происходит идеально. Т.е. приходит заказчик, дядя Вася вырезает фигурку, заказчик с фигуркой уходит, в этот момент дяде Васе приспичило сходить в туалет, когда он возвращается из туалета, то в этот момент приходит новый заказчик и т.п. Наличие или отсутствие Лёши в данном случае так же никакой роли не играет. Т.е. если процессор должен исполнить одну или несколько задач, которые вполне успевают обработаться на одном процессоре в режиме "по очереди" (а именно так устроена многозадачность в операционных системах), то мы будем иметь полную загрузку процессора, но при этом ещё не появляется нехватка процессорного времени, а потому в таком предельном случае "двухпоточный" процессор работает с той же производительностью, что и "однопоточный"

Далее возьмём случай, когда заказчиков много и уже начинает образовываться очередь, т.е. дядя Вася при 100% загрузке не успевает обслуживать всех клиентов и возникает реальный простаивание топора (т.е. работа есть, а топор свободен). В этом, и только в этом случае начинает играть свою роль Лёша, заполняя полезной работой те интервалы времени, в которых при его (Лёши) отсутствии топор бы простаивал. При этом Лёша работает мало, дядя Вася проводит в туалете времени меньше, чем в работе. Именно поэтому роль второго плотника выполняет маленький Лёша, а не брат дяди Васи дядя Петя. Хотя в реальном "двухпоточном" процессоре два логических ядра одинаковы и строго правильным было бы работать с образом дяди Пети, а не с Лёшей. Таким образом, если полезная нагрузка, которую необходимо вычислить на процессоре, выше некоего предельного случая, то "двухпоточный" процессор, в основном, начинает показывать немного более высокую производительность, но только при наличии задач, которые можно исполнять параллельно. Т.е. если у нас есть тяжёлая игра, разработчики которой никак не реализовывали "многопоточное" исполнение, то при запуске игры мы не увидим разницы на "однопоточном" и на "двухпоточном" процессорах. При условии, что игра - единственная запускаемая задача и в параллель никакие другие задачи не исполняются. Но если игра внутри себя умеет какие-то вычисления распараллелить на два потока или параллельно игре запущена ещё какая-нибудь задача, потребляющая процессорное время, то мы увидим, что у "двухпоточного" процессора более высокая производительность. И выражаться это будет вовсе не в том, что на "двухпоточном" процессоре игра будет работать быстрее, а в том, что на "двухпоточном" процессоре игра будет тормозить меньше. В реальной жизни прирост производительности можно оценить как "до 5-15%" в зависимости от конкретной задачи, а не в 100%, как это может показаться из рекламы. Идея процессоров с hyperthreading заключается в том, чтобы получить эти самые "до 5-15%" производительности при увеличении стоимости процессора на 5%

Откуда берутся интервалы времени, в которых вычислительное устройство простаивает? Современные процессоры представляют собой суперскаляры. Т.е. в процессорном конвейере на самом деле есть несколько исполнительных устройств. При исполнении программы процессор автоматически ищет отдельные инструкции, которые можно исполнить параллельно и одновременно исполняет их на разных устройствах. Но не всегда получается загрузить все устройства (не всегда в программе имеется достаточная параллельность на уровне инструкций), а потому свободное устройство может поиспользовать другое логическое ядро. Процессор иногда обращается в память, и если данных нет в кэше первого уровня, то возникает ожидание, пока данные подкачаются из кэша второго или третьего уровня или из памяти. В последнем случае задержка может составлять несколько десятков тактов, в течение которых конвейер ничего не делает, а ждёт данных из памяти. И всё это время другое логическое ядро можно использовать для того, чтобы что-нибудь посчитать на пустующем конвейере. Походы дяди Васи в туалет являются аналогами этих простоев конвейера, которые заполняет второе логическое ядро

Однако бывают случаи, когда дяде Васе приходится играть партию в карты. В реальной жизни это эквивалентно тому, что оба логических процессора, например, полезли в одну и ту же строку памяти или оба логических процессора очень интенсивно работают с памятью, выбивая друг у друга данные из кэша. Потому что несмотря на два логических процессора (сие справедливо в том числе и для многоядерных процессоров), память всё-таки общая, и контроллер памяти обслуживает логические процессоры по очереди, а не параллельно (я не буду сейчас вспоминать про всякие NUMA и тому подобные случаи). Поэтому в некоторых случаях "двухпоточный" процессор может тормозить больше, чем "однопоточный".

4. Заключение

Данный пример нужно рассматривать именно как пояснения "на пальцах". Реальный процессор устроен намного сложнее. Исполнение нескольких задач в современных операционных системах так же устроено намного сложнее. Да и работа операционной системы в этом аналоге никак не затрагивается. Статья в первую очередь посвящена людям, далёким от программирования или компьютерного железа. Хочется верить, что после статьи, увидев в диспетчере оборудования "2 ядра, 4 потока" и 4 картинки процессоров, появится некоторое понимание, что в машине реально приблизительно 2.2 (два целых, две десятых) процессорных ядра, а вовсе не 4

*** UPDATE
Строго говоря, процессорное ядро без hyperthreading'а следует рассматривать как эквивалент 0.9 (ноль целых, девять десятых) ядра с точки зрения производительности. Т.е. в реальной жизни такое ядро в среднем в состоянии выжать лишь 90% от теоретически возможной производительности. А процессорное ядро с hyperthreading'ом следует рассматривать как эквивалент 1 ядра с точки зрения производительности, т.к. hyperthreading позволяет довести эффективность процессорного ядра до 100% от теоретической производительности. Правда только в тех случаях, когда есть реальные параллельные вычисления. Ни о каком ускорении в два раза, к чему нас пытаются подвести маркетологи, вводя понятия "1 ядро / 2 потока", речи не идёт

5. Покупать или не покупать процессор с hyperthreading'ом?

Здесь бы мне хотелось высказать мои личные соображениями по вопросу "покупать или не покупать процессор с hyperthreading'ом". Соображения носят ознакомительный характер, я ни в коем случае их не навязываю. Во всех описываемых случаях я предполагаю выбор между двумя процессорами, которые отличаются только наличием hyperthreading'а.

*** UPDATE
При указанных выше ограничениях всё сводится к тому, что мы рассматриваем только теоретические процессоры, т.к. в реальной жизни не бывает такого, чтобы процессоры отличались только наличием hyperthreading'а. В реальности процессоры с hyperthreading'ом оснащаются дополнительным объёмом кэша и в силу некоторых особенностей имеют более высокую частоту. В итоге прирост производительности будет составлять не описанные условные +10%, а условные +15% или даже условные +20% (всё очень сильно зависит от конкретных задач). Изначально весь раздел был написан именно для таких теоретических процессоров. Поэтому данный раздел теряет смысл в качестве практического совета при покупке процессора. Его следует рассматривать, как сравнение процессоров для различных задач. А дальше пусть каждый решает сам для себя, готов ли он платить лишние условные 30% денег для получения условных 15% производительности. Основная цель статьи заключается в том, чтобы объяснить людям, что процессор "1 ядро/2 потока" вовсе не в два раза быстрее процессора "1 ядро/1 поток"

Процессор "1 ядро/1 поток - 1 топор/1 плотник" vs "1 ядро/2 потока - 1 топор/2 плотника (hyperthreading)" - одноядерные процессоры с отсутствием и наличием hyperthreading'а. Однозначно покупать hyperthreading. Возможный прирост производительности в данном случае играет второстепенную роль, а первостепенную роль играет то, что появляется какая-никакая, а возможность настоящего параллельного исполнения программ. Второе логическое ядро (недопроцессор) сгладит тормоза в тех случаях, когда при исполнении тяжёлой задачи (игрушки, кодировщика видео, компилятор, 3d-рендеринг - всё в однопоточном режиме) параллельно запускаются маленькие лёгкие задачи (аська, блокнот, проводник, программа для скачивания файлов). В этом случае первое логическое ядро будет заниматься исполнением тяжёлой задачи, а второе логическое ядро (недопроцессор) - исполнением мелких задач, которые не требуют много ресурсов. Но если бы они исполнялись на основном ядре (в случае отсутствия hyperthreading'а), то они отнимали бы ресурсы у тяжёлых задач. Перечисленные случаи являются статистически значимыми для большинства пользователей, процессорами "1 ядро/2 потока" в наши дни оснащаются, в основном, недорогие нетбуки и ноутбуки, у которых и так производительность невысокая, а потому немножечко лишней производительности за счёт параллельности однозначно не помешает.

Процессор "2 ядра/2 потока - 2 топора/2 плотника" vs "2 ядра/4 потока - 2 топора/4 плотника (hyperthreading)", процессор "4 ядра/4 потока - 4 топора/4 плотника" vs "4 ядра/8 потоков - 4 топора/8 плотников (hyperthreading)" и т.д. - многоядерные процессоры с отсутствием и наличием hyperthreading'а. Наличие двух и более ядер уже само по себе делает процессор достаточно производительным в плане одновременного исполнения задач, а поэтому ответ на вопрос здесь не такой однозначный, как для случая с одноядерным процессором. Условные 10% прироста производительности, которые даёт hyperthreding, можно рассматривать с двух позиций: сокращение времени исполнения счётных задач (например, кодирование видео происходит за 60 минут, или за 54 минуты) либо более детализированное представление в задачах, работающих в реальном времени (например, скорость прорисовки в игрушке 50 кадров в секунду или 55 кадров в секунду). Если вы предполагаете работать с задачами, которые умеют исполняться в распараллеленном режиме и ускорение нужно именно как сокращение времени работы (кодирование видео, компиляция больших проектов, трёхмерный рендеринг), то ответ на вопрос - "да, нужно покупать процессор с hyperthreading", т.к. это, скорее всего, ускорит вашу работу. Если вам нужны задачи в реальном времени, а именно - игрушки, ускорение для которых означает увеличение количества кадров в секунду, то ответ на вопрос - "нет, покупать процессор с hyperthreding'ом смысла НЕ имеет". Во-первых, увеличение скорости от 50 до 55 кадров в секунду на глаз всё равно заметно не будет. Во-вторых, производительность игрушке в гораздо большей степени зависит от видеокарты, а не процессора, и наличие дополнительных недопроцессоров с очень большой вероятностью ощутимо не отразится на производительности игры.

Процессор "1 ядро/2 потока - 1 топор/2 плотника" vs "2 ядро/2 потока - 2 топора/2 плотника (hyperthreading)" - одинаковое количество потоков на процессорах с разным количеством физических ядер. Вариант с одним ядром имеет смысл брать только в тех случаях, когда предполагается офисный вариант использования (браузер, программы для обработки текстовых документов), а потому вполне достаточно варианта, описанного в абзаце про одноядерные процессоры (когда дополнительный недопроцессор служит исключительно для сглаживания тормозов). Как только появляется более тяжёлая работа, которая умеет исполняться в распараллеленном (обработка двухмерной и трёхмерной графики, обработка звуков, отображение и обработка видео, игры, компиляция), то лучше покупать два ядра. При покупке недорогих нетбуков и ноутбуков я бы так же порекомендовал покупать 2 ядра, т.к. на слабых процессорах возникают тормоза даже на лёгких задачах (например, параллельно запущенные текстовый редактор и браузер)

При покупке нетбука или ноутбука, для которого критично время автономной работы, нужно учитывать, что двухядерный процессор жрёт, грубо говоря, в два раза больше электричества, чем одноядерный (в том числе и с наличием hyperthreading), а четырёхядерный процессор жрёт в два раза больше электричества, чем двухядерный. В энергосберегающем режиме процессоры работают на пониженной частоте, но ненужные ядра не отключаются, а поэтому они продолжают жрать электричество.

6. Ссылки на темы, где обсуждался данный вопрос

7. Внешние ссылки по данной тематике
  • http://testlabs.kz/processors/705-test-hyper-threading.html
    По ссылке полезно посмотреть замеры производительности в играх. К замерам приводится комментарий, объясняющий причину возникающей разницы, но, подозреваю, что причины описаны как результат общих рассуждений, а не как достоверно измеренный факт
  • http://www.overclockers.ru/lab/35826...g_v_igrah.html
Просмотров 15270 Комментарии 90
Всего комментариев 90
Комментарии
  1. Старый комментарий
    Аватар для dimank666
    что-то очень сложно написано, мне окажется можно проще объяснить
    Запись от dimank666 размещена 21.01.2014 в 23:13 dimank666 вне форума
  2. Старый комментарий
    Аватар для Evg
    А что именно сложно. С дядей Васей или с проведением аналогий?
    Запись от Evg размещена 21.01.2014 в 23:18 Evg вне форума
  3. Старый комментарий
    Не знаю что сложного
    меня повеселило
    единственно что замыливается вопрос
    что важнее производительность дяди Васи или производительность топора
    Запись от ValeryS размещена 21.01.2014 в 23:29 ValeryS вне форума
  4. Старый комментарий
    Аватар для MrGluck
    Хорошо написано, читается в удовольствие и остается в памяти
    Запись от MrGluck размещена 21.01.2014 в 23:37 MrGluck вне форума
  5. Старый комментарий
    Аватар для Evg
    Цитата:
    Сообщение от ValeryS Просмотреть комментарий
    единственно что замыливается вопрос
    что важнее производительность дяди Васи или производительность топора
    Да, хорошая мысль. Надо подумать, как это хорошо объяснить.
    Производительность дяди Васи - это загрузка, которая состоит из полезной нагрузки (загрузка топора) + неполезный простой (поход в туалет). Если посмотреть в на загрузку одноядерного однопоточного процессора в диспетчере задач, то 100% загрузка означает на самом деле 100% загрузку процессорного времени, но не 100% загрузки конвейера (т.е. конвейер работает не на 100% теоретической производительности). Второй логический процессор позволяет довести загрузку конвейера до 100%, что будет эквивалентно 105-115% загрузки в терминах процессорного времени (в диспетчере задач).

    Как-то сумбурно пояснил. Надо подумать, как попроще
    Запись от Evg размещена 22.01.2014 в 00:07 Evg вне форума
  6. Старый комментарий
    Аватар для talis
    Классная статья! Как в старые добрые времена, когда ещё в школьное время читал всякие комповые журналы. Ностальгия...

    Три вопроса (может, на деле больше):

    1) Дядя Вася успевает доделать фигурку до того, как снова пойдёт в туалет, или может быть такое, что он откладывает топор и фигурку в недоделанном виде и уходит? В этом случае Лёша же делает свою фигурку, не фигурку дяди Васи? И когда дядя Вася возвращается, Лёша бросает свою фигурку недоделанной и немедленно отдаёт топор дяде Васе, или всё же дядя Вася стоит и ждёт, пока Лёша закончит свою работу?

    2) Корова рыжая одна (железка то бишь), брали мы её одну. А плотника два (ядра логических). Кода дядя Вася идёт в туалет, что происходит? Аппаратное прерывание? Как Лёша перехватывает инициативу, куда девает значения регистров и другие части фигурки дяди Васи, и как потом дядя Вася, вернувшись из своего прерывания, перехватывает инициативу назад? Как они координируются? И тогда уж, до кучи, где лежат данные, которые пришли из памяти, пока дядя Вася ждёт, пока Лёша доделает свою фигурку?

    3) Дядя Вася и Лёша - это логические ядра. Как они "выглядят" (существуют, что ли) на железном уровне? Почему, например, два, а не четыре или вообще не три? Чем ограничено их количество. Вообще, какая неведомая тёмная сила ими управляет, если можно так выразиться?

    Спасибо!
    Запись от talis размещена 22.01.2014 в 16:56 talis вне форума
  7. Старый комментарий
    Аватар для Evg
    Как устроен двухпоточный процессор изнутри детально, я не знаю. Я не думаю, что такая информация где-то публикуется, поскольку программисты её никак не должны учитывать. Операционная система должна знать только то, что имеется двухпоточный процессор, который нужно рассматривать, как, условно говоря, 1 процессор и один небольшой довесок (недопроцессор). Как это всё устроено изнутри - операционную систему не должно волновать, а пользовательские программы - и подавно. Даже если такая информация есть, то не думаю, что моей квалификации хватит, чтобы понимать, как оно устроено изнутри. Я программист, а не разработчик аппаратуры, а потому подозреваю, что кроме предлогов и междометий я и слов-то знакомых там не увижу

    Цитата:
    Сообщение от talis Просмотреть комментарий
    1) Дядя Вася успевает доделать фигурку до того, как снова пойдёт в туалет, или может быть такое, что он откладывает топор и фигурку в недоделанном виде и уходит? В этом случае Лёша же делает свою фигурку, не фигурку дяди Васи? И когда дядя Вася возвращается, Лёша бросает свою фигурку недоделанной и немедленно отдаёт топор дяде Васе, или всё же дядя Вася стоит и ждёт, пока Лёша закончит свою работу?
    В этой грубой модели нас интересует только конечная производительность - количество выпускаемых фигурок в заданный интервал времени. Конкретный алгоритм работы дяди Васи и Лёши роли не играет, потому что на выходе мы получим одну и ту же цифру производительности. Алгоритм работы дяди Васи и Лёши - это то, что выпускает в железе производитель микропроцессора. Алгоритм того, как заказчики перебегают из очереди в очередь - это то, как планирует задачи операционная система

    Цитата:
    Сообщение от talis Просмотреть комментарий
    2) Корова рыжая одна (железка то бишь), брали мы её одну. А плотника два (ядра логических). Кода дядя Вася идёт в туалет, что происходит? Аппаратное прерывание? Как Лёша перехватывает инициативу, куда девает значения регистров и другие части фигурки дяди Васи, и как потом дядя Вася, вернувшись из своего прерывания, перехватывает инициативу назад? Как они координируются? И тогда уж, до кучи, где лежат данные, которые пришли из памяти, пока дядя Вася ждёт, пока Лёша доделает свою фигурку?
    Никаких дополнительных прерываний нет. Снаружи двухпоточное ядро работает точно так же, как процессор с двумя однопоточными ядрами (т.е. если первое логическое ядро по каким-то причинам простаивает, то операционная система не получает никаких прерываний, а второе логическое ядро автоматически начинает загружать конвейер). Двухпоточное ядро реализовано на одном кристалле (т.е. это замкнутая система), второе логическое ядро узнаёт о простаивающем конвейере без каких-либо внешних прерываний и т.п. - это исключительная внутренняя логика процессора

    Каждое логическое ядро - это, грубо говоря, набор регистров для хранения значения плюс довольно небольшие прибамбасы. Далее идут мои догадки, как это можно было бы реализовать.

    Допустим, основная задача работает на ядре-1 и при этом образовалась ситуация, когда ядру-1 нечем загрузить конвейер. Второе ядро, узнав о том, что ядро-1 пока не хочет нагружать конвейер, переводит рубильник конвейера из положения "работать с регистрами из ядра-1" в положение "работать с регистрами из ядра-2". При этом рубильник - это не статическая вещь, а множество рубильников, которые привинчены к каждой стадии конвейера и так же двигаются по конвейеру. Как только ядро-1 находит данные, которые можно закинуть на конвейер, то на стадии, находящейся на входе конвейера переключает рубильник в положение "работать с регистрами из ядра-1" и первая стадия конвейера начинает исполнять задания из ядра-1. В этот момент вторая стадия и далее имеют рубильники в положении "работать с регистрами из ядра-2", а потому спокойно завершают исполнение тех операций, которыми нагрузило конвейер ядро-2. Т.е. конвейер работает в своём штатном режиме, добавляется только рубильник, который говорит, с которым из логических ядер работает конвейер, за счёт чего различные стадии конвейера исполняют задания с разных логических ядер

    Как происходит отрабатывание ситуации, когда конвейер застрял на длинном обращении в память - я тут уже чего-то разумного предположить не могу.

    Цитата:
    Сообщение от talis Просмотреть комментарий
    3) Дядя Вася и Лёша - это логические ядра. Как они "выглядят" (существуют, что ли) на железном уровне? Почему, например, два, а не четыре или вообще не три? Чем ограничено их количество. Вообще, какая неведомая тёмная сила ими управляет, если можно так выразиться?
    Обычное железное ядро состоит из регистрового файла (набора регистров), исполняющих устройств (конвейера), всяких приблуд по работе с внешней аппаратурой и памятью. Двухпоточное ядро выглядит почти так же, только некоторые (небольшие) компоненты удваиваются: регистровый файл и ещё что-то. Ну и добавляется немного всякого хлама, типа описанных выше рубильников. Когда вышли первые процессоры с hyper-threading'ом (вроде бы это были pentium-IV), то тогда оценивалось, что площадь кристалла увеличивается на 5%, причём дублируются более простые в техническом исполнении узлы. А сложный и тяжёлый в исполнении конвейер остаётся практически таким же. Ну и на операционную систему ложится задача по правильному планированию процессов (т.е. нужно учитывать, что второе логическое ядро - это недопроцессор).

    Почему их только два? А зачем больше. Ведь дядя Вася и Лёша бегают в сортир НЕ одновременно. Т.е. если бы в мастерской был ещё Коля, то он бы практически всегда сидел бы и нифига не делал, включаясь в работу только в тот момент, когда дядя Вася и Лёша пошли в туалет одновременно. Так же и в железе, как только первое логическое ядро начинает халявить - конвейер тут же занимает второе ядро. Ситуации, когда халявят оба ядра - очень редкие, а потому прикручивание третьего ядра практически никакой пользы не несёт, а вот засинхронизировать три ядра намного сложнее, чем два

    Никакая неведомая сила логическими ядрами не управляет. Они сами собой управляют и работают как два независимых процессорных ядра. Вот только исполняющее устройство у них одно, но делят они его между собой сами, не прибегая к помощи извне
    Запись от Evg размещена 22.01.2014 в 21:33 Evg вне форума
  8. Старый комментарий
    Аватар для Evg
    Да, вот ещё момент. Для более приближенного описания реального процессора наша мастерская должна состоять из, допустим, четырёх дядей Васей, четырёх Лёш и четырёх топоров, т.к. современные процессоры внутри себя имеют несколько конвейеров

    Приведу примеры "плохого" и "хорошего" с точки зрения распараллеливания кода. Речь идёт о машинных кодах, но для удобства напишу их на языке программирования.

    C
    /* "Плохой" код, т.к. здесь ничего нельзя исполнить параллельно,
     * т.к. все операции сложения зацеплены друг за друга */
    a = ((b + c) + d) + e;
    C
    /* "Хороший" код, т.к. здесь можно параллельно выполнить "b+c" и "d+e" */
    a = (b + c) + (d + e);
    Исполняющее устройство имеет несколько конвейеров. Процессор автоматически ищет в коде инструкции, которые можно исполнить параллельно, и закидывает их исполнять на разные конвейеры одновременно. Понятно, что реальный код никогда не будет написан так, что всегда будут загружены все конвейеры, а потому и возникают простои. Для "плохого" кода конвейеры будут простаивать больше, чем для "хорошего". А потому эффект увеличения производительности сильно зависит от качества кода. Если постараться и написать очень плохой код, то вполне может получиться так, что на двухпоточном процессоре две такие программы, запущенные в параллель отработают по времени так же, как и одна задача (т.е. +100% производительности). Именно за счёт того, что из-за невозможности распараллелить на уровне инструкций, рубильники на какие-то конвейерах будут всегда находиться в положении "работать с регистрами из ядра-1", а на остальных конвейерах - "работать с регистрами из ядра-2". В момент появления первых процессоров с hypertherading'ом ситуация была скорее "плохая", чем "хорошая", поскольку имелась масса кода, скомпилированного без учёта суперскалярности (несколько-конвейерности) процессора или с учётом маленького количества конвейров (на pentium их было всего два). На сегодняшний день hyperthreading менее актуален, т.к. уже прочно вошли в жизнь многоядерные процессоры, и основной массе пользователей востребованная загрузка "в ширину" вполне укладывается в количество процессорных ядер. Hyper-threading - это скорее маркетинговая фича, потому что, условно говоря, при 5%-ном увеличении стоимости выпуска процессора с hyperthreading'ом, стоимость процессора в магазине может быть на 10-20-30% выше аналогичного процессора без hyperthreding'а, потому что есть много покупателей, готовые брать самое дорогое, не обращая внимание на соотношение цена/качество
    Запись от Evg размещена 22.01.2014 в 21:52 Evg вне форума
  9. Старый комментарий
    Аватар для talis
    Цитата:
    Сообщение от Evg Просмотреть комментарий
    Процессор автоматически ищет в коде инструкции, которые можно исполнить параллельно, и закидывает их исполнять на разные конвейеры одновременно.
    То есть когда код поступает в процессор, есть некий блок, который просматривает все инструкции "на входе" и раскидывает их по конвеерам?
    Запись от talis размещена 23.01.2014 в 21:24 talis вне форума
  10. Старый комментарий
    Аватар для Evg
    Типа того. В intel'овских процессорах много чего есть помимо простого раскидывания по конвейерам. При этом компилятор, зная как устроен тот или иной процессор, умеет подстравивать код под конкретный конвейер (под конкретную архитектуру процессора), чтобы он работал максимально производительно
    Запись от Evg размещена 23.01.2014 в 22:38 Evg вне форума
  11. Старый комментарий
    Аватар для dimank666
    ну вообще я думаю стоило бы описать этот процесс по другому
    допустим в мастерской(ядро процессора) работает Петя и Вася
    Петя делает стулья.
    Вася делает столы.
    (Этим я показываю что в ядре процессора есть несколько модулей)

    Значит у нас есть тупые заказчики (типа одно поточные программы) которые приходя говорят нам нужен стул, когда стул сделают, они опять приходят и говорят нам нужен стол, или наоборот

    И умные заказчики (типа много поточные программы) которые приходят и говорят нам нужен стол и стул

    Пусть также будет 2 очереди основная и дополнительная (два потока)
    ========================================================
    Вот и получается если они берут заказ от умного заказчика то оба заняты работой.
    А если подается тупой заказчик, то Петя или Вася идет и берут заказ из дополнительной очереди.
    Запись от dimank666 размещена 24.01.2014 в 22:04 dimank666 вне форума
  12. Старый комментарий
    Аватар для Evg
    Твоя модель НЕ правильно описывает логику двухпоточного ядра. Твоя модель описывает поведение двухядерного процессора. А это совсем не то. Это НЕ hyperthreading

    Я бы даже сказал вводит людей в заблуждене
    Запись от Evg размещена 25.01.2014 в 13:47 Evg вне форума
    Обновил(-а) Evg 25.01.2014 в 23:42
  13. Старый комментарий
    Аватар для dimank666
    И чем же не правильно описывает моя модель?

    а вот из ваше описание еще сложнее получается, к тому же я считаю что и неправильно
    есть дядя Вася который только 1 топором обрабатывает поленья, (следовательно блок обработки данных в процессоре всего 1)
    туалет тут вообще какое значение имеет?
    если блок обработки один, получается если дядя Вася обрабатывает 10 бревен в час не ходя в туалет
    то даже если он уйдет в туалет то производительность также и останется 10 бревен в час, так как пока он в туалете за него работает сын. следовательно откуда берется прирост производительности если за одно и тоже время, в независимости, где был дядя Вася, количество обработанных бревен не изменилось
    Запись от dimank666 размещена 26.01.2014 в 20:18 dimank666 вне форума
  14. Старый комментарий
    Аватар для dimank666
    что касается модели двух ядерного процессора, то тут уже будет по другому
    вот модель двухъядерного процессора на том же примере только без Hyper-threading

    допустим в мастерской(2 ядра) работает Петя и Вася и в соседнем кабинете Леша и Антон
    Петя и Леша делают стулья.
    Вася И Антон делают столы.
    (Этим я показываю что есть 2 независимых ядра с несколькими модулями)

    Значит у нас есть тупые заказчики (типа одно поточные программы) которые приходя говорят нам нужен стул, когда стул сделают, они опять приходят и говорят нам нужен стол, или наоборот

    И умные заказчики (типа много поточные программы) которые приходят и говорят нам нужен стол и стул

    Пусть также будет 2 очереди основная и дополнительная (два потока) пусть их даже будет хоть 10
    ========================================================
    А вот теперь в чем разница
    Так как Hyper-threading нет то приходит тупой заказчик говорит например мне нужен стол следовательно Вася берет заказ, следовательно Петя сидит без дела

    даже если придут 2 тупых заказчика то первый заказ будут делать Петя и вася а второй Антон и Леша но самое главное что по 1 рабочему в зависимости от заказа будет бездельничать в каждом кабинете
    Запись от dimank666 размещена 26.01.2014 в 20:37 dimank666 вне форума
  15. Старый комментарий
    Аватар для Evg
    > туалет тут вообще какое значение имеет?

    Простой конвейера

    > если блок обработки один, получается если дядя Вася обрабатывает 10 бревен в час не ходя в туалет
    > то даже если он уйдет в туалет то производительность также и останется 10 бревен в час

    Если взять процессор без hyperthreading'а, то производительность будет не 10, а 9 брёвен в час. Другими словами, если мы имеет обычный одноядерный процессор, то в реальной жизни он никогда не будет загружен на 100% от теоретической производительности. И есть две основные причины: ни одна программа (кроме искусственных) не в состоянии всегда использовать все конвейеры и периодические обращения в память всегда вызывают остановку конвейера, т.к. память медленно работает

    > так как пока он в туалете за него работает сын

    А вот сын - это и есть второй поток в одном ядре. Т.е. дядя Вася и сын суммарно составляют hyperthreading. Дядя Вася и Лёша напару умеют загрузить топор так, чтобы он не простаивал. Таким образом hyperthreading - это ни что иное, как попытка заставить процессорное ядро работать на 100% от теоретической производительности за счёт добавления логического ядра, которое, выполняя роль недопроцессора, сумеет нагрузить конвейер в местах простоя. По честному, ускорение от hyperthreading'а составляет не от 100% до 115%, а от 85% до 100% от теоретической производительности конвейера. В те дни, когда hyperthreading появился реальная цифра составляла, грубо говоря, на 85%, а 50%, потому что старые бинарники плохо распараллеливались, а потому видимы прирост на первых процессорах с hyperthreading'ом был намного больше, чем в наши дни

    > что касается модели двух ядерного процессора, то тут уже будет по другому

    Да ради бога. Но в рамках данной темы это не интересно, поскольку речь идёт об одноядерном двухпоточном процессоре, а не о двухядерном процессоре

    > Так как Hyper-threading нет то приходит тупой заказчик

    "Так как Hyper-threading нет" не в тему, поскольку отсутствие hyperthreading'а никак не является причиной, по которой заказчик является тупым
    Запись от Evg размещена 26.01.2014 в 23:49 Evg вне форума
  16. Старый комментарий
    Аватар для AzaKendler
    лучшеб сказали просто спасибо Евгению, что вообще хоть что то полезное пишет. Таких мало тут
    Запись от AzaKendler размещена 26.01.2014 в 23:51 AzaKendler вне форума
  17. Старый комментарий
    Аватар для Evg
    Ключевым моментом является топор, а не плотники, т.к. по максимуму нужно загрузить именно его.

    В процессоре Core i3-3220 имеется 2 топора и 4 плотника
    В процессоре Core i5-3570 имеется 4 топора и 4 плотника
    В процессоре Core i7-4770 имеется 4 топора и 8 плотников
    Запись от Evg размещена 26.01.2014 в 23:53 Evg вне форума
  18. Старый комментарий
    Аватар для Evg
    > И чем же не правильно описывает моя модель?

    Я уже сказал, чем. Твоя модель описывает двухядерный процессор, что вовсе не является hyperthreding'ом. А точнее, в твоей модели нет ничего, что описывало бы hyperthreading. Двухядерный процессор с hyperthreading'ом - это core i3 (2 ядра, 4 процессора). В твоей модели есть "2", но нету "4"
    Запись от Evg размещена 26.01.2014 в 23:55 Evg вне форума
  19. Старый комментарий
    Аватар для talis
    Да, Евгений, спасибо Вам огромное за Ваш блог и Ваши посты на форуме. Классно, что можно общаться с настоящим специалистом на темы, для изучения которых одного гугла и книжек мало!
    Запись от talis размещена 27.01.2014 в 00:12 talis вне форума
  20. Старый комментарий
    Аватар для Evg
    В итоге появилось понимание, что для полноты картины нужно ещё как минимум две статьи, описывающие на такой же модели работу многозадачной операционной системы и работу многоядерного процессора
    Запись от Evg размещена 27.01.2014 в 11:19 Evg вне форума
    Обновил(-а) Evg 27.01.2014 в 11:20
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru