Через тернии к звёздам или как увеличивали производительность процессоров.

для раздела Блоги

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

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

Следующим шагом в развитии компьютеров стали электромеханические устройства, т.е. компьютеры, построенные на электромеханических реле. Об одном из создателей таких машин Конрада Цузе можно почитать на http://www.3dnews.ru/editorial/konrad_zuse. Уже тогда наметилась тенденция увеличивать частоты работы. Ведь очевидно чем быстрее выполняется одна операция (чем больше частота) тем быстрее выполняется вся задача (к слову сказать, это не всегда так, но об этом ниже). Тот же самый Цузе увеличил частоту своих машин с 1Гц до 22Гц и это для механических реле!!! (ох, наверное, та ещё «трещотка» была ).

Дальнейший рост частот был крайне сложен. К тому времени уже были изобретены электровакуумные лампы (к слову сказать, они были изобретены, до того как Цузе построил первую свою машину). Эти вычислительные машины могли работать на частотах уже порядка кологерц и даже 100кГц, т.е. 1000
- 100 000 операций в секунду, но эти машины занимали несколько комнат. Тем не менее, скачок по частоте существенный. Вот несколько примеров таких машин: ENIAK, Mark -1.

В 50х – 60х годах были изобретены полупроводниковые транзисторы. Первые транзисторы не выигрывали по частотным характеристикам у ламп, но существенно выигрывали у них по энергопотреблению и размерам. Компьютеры стали умещаться в 1-м шкафу и стали существенно дешевле (в место миллионов $ десятки тысяч $), а, следовательно, и доступнее. Кроме того, транзисторы дали предпосылку появления микросхем.

Итак, вот мы и подобрались к более менее близким родственникам современных ПК. Микросхема, по сути, это множество транзисторов. Уже в 1964г был построен первый компьютер на микросхемах. Кроме того микросхемы позволили увеличивать частоты, за счёт миниатюризации. Попробую пояснить на пальцах: как известно ток проводят электроны (хотя и не всегда) так вот чем больше транзистор, тем больше расстояние надо пролететь расстояние электрону и тем больше это у него займёт время. Если транзистор уменьшить то электрон будет быстрее пролетать заданное расстояние, а, следовательно, транзистор сможет работать на большей частоте. Поэтому при утоньшение тех процесса увеличивается частотный потенциал. К тому же в микросхеме меньше расстояние передачи сигнала и линии передача работают на высоких частотах. Например, советский микропроцессор КР580 работал на частоте 2МГц.

Поначалу процессор, память и шина между ними работали на одной частоте. Но частота процессора могла увеличиваться намного больше, чем его окружение, т.е. память не давала работать процессору на высокой частоте. Тогда инженеры придумали: а давайте сделаем частоту процессора кратной частоте работы системной шины, т.е. решили сделать коэффициент умножения. Что бы процессор мог работать на большей чем память частоте и при этом не зависеть от данных, у него появилась небольшая собственная память, работающая на той же частоте, что и он сам, и располагавшееся в самом процессоре. Чтобы ещё лучше согласовать работу процессора с памятью эта память была 2х уровневой. Вот так и появилась Кеш память L1 и L2. В некоторых процессорах L2 располагался не в процессоре, а около него и работал на частоте меньшей, чем процессор, но большей чем шина. Первым процессором с коэффициентом умножения стал i486DX2-50. Справедливости ради следует отметить, что кеш появился до появления множителя ещё в 486-м. Чем больше Кеш тем меньше вероятность что процессор будет простаивть в ожидании данных из оперативной памяти.

В современных процессорах транзистор может работать на частотах в десятки ГГц, но, тем не менее, процессоры не работают на таких частотах. Так в чём же дело? Давайте разбираться. Для объяснения этого феномена я построил небольшую схему в программе Micro-Cap десятичного счётчика. Так как схема содержит более 100 транзисторов то я её нарисую достаточно упрощённо.


схема десятичного счётчика

При достаточно низкой частоте все импульсы прямоугольные схема считает от 0, 1… до 9, а потом идёт 0.


(кликните по картинке для увеличения)

правильная работа счётчика


(кликните по картинке для увеличения)

неправильная работа счётчика

При увеличении частоты возникают ошибки (обведены красным кругом), эти ошибки возникают за счёт накопления ошибок в каждом каскаде. Что это значит? Это значит, что компьютер будет считать 2+2=13 или что-то в этом роде. Что это значит для пользователя? Это значит, что если вы переразогнали свой процессор то у вас не загружается виндовс, а если и загружается то зависает. Избежать этого можно 2мя способами: снизить частоту или увеличить напряжение питания, но при увеличении питания увеличивается выделяемая мощность. Проблему с мощностью мы ещё рассмотрим ниже.

Разработчики процессоров нашли интересный выход из этой ситуации: они придумали сделать конвейер. Разделим сложную операцию на несколько простых, и пусть одна простая выполняется за 1 такт, но этот такт можно сделать короче, т.е. увеличить частоту. Приведу пример выгоды конвейера из несколько другой области: сборка автомобиля на конвейере от начала до конца занимает несколько часов, но готовые автомобили выходят с конвейера каждую минуту. Примерно что-то в этом роде происходит и в современных процессорах, но есть пару моментов, о которых я расскажу ниже. Первым процессором с конвейером стал 486й. Он имел 5 стадий конвейера. Пентиум 3 имел 10 стадий. Пентиум 4 Northwood– 20 Prescott - 31. AMD K8 – 12. Дело в том, что в программе могут быть переходы, поэтому процессор должен правильно планировать исполнение операции. Если процессор спланирует неправильно, то сбросится весь конвейер и чем он длиннее, тем больше мы потеряем. Кроме того, в П4 был эффект Replay (более конкретно о нём можно почитать тут http://www.fcenter.ru/online.shtml?articles/hardware/processors/12033). Такие явления как сброс конвейера и Replay часто сводили на нет выигрыш от высокой частоты П4. В тестах П4 проигрывали процессорам АМД. Именно это явление заставило пересмотреть политику INTEL по дальнейшему увеличению частот за счёт увеличения конвейера и разработать процессор Core2Duo (Сonroe) с 14 стадиями конвейера.

Ещё одна причина не позволяющая увеличивать частоту это тепловыделение. Посмотрим на график выделяемой мощности в приведенной выше схемы:


(кликните по картинке для увеличения)

график выделяемой мощности

Из этого графика можно сделать следующие выводы:
1.Тепло выделяется только во время переходных процессов. Это связано с тем, что при логической единице ток, протекающий через транзистор мал, практически равен 0, а при логическом нуле напряжение на транзисторе мало. Как известно (ну если в школу на физику не забивали ) мощность равна произведению тока на напряжение P=I*U, таким образом, и при 0 и при 1, Р мало, но вовремя переходного процесса ни напряжение, ни ток не равны 0 и выделяется мощность. Чем больше частота, тем больше будет переходных процессов и тем больше будет выделяться тепла. Таким образом, потребляемая мощность растёт линейно от частоты.
2.Выбросы не всегда одинаковые. Это связано с тем, что в разные моменты времени переключается разное количество логических схем. Получается, что мощность не совсем по линейному закону растёт, а может отклоняться относительно этого закона.

Также мощность растёт с увеличением напряжения питания: P=U2/R, где R некое среднее сопротивление, которое зависит от технологии изготовления микросхемы.

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

До сих пор я рассматривал увеличения производительности процессора только за счёт увеличения частоты, но что если нам выполнять за один такт не одну операцию, а несколько. Но как? Спросите вы, ведь программа должна выполняться последовательно. Поясню на примере:

1 С=A+B
2 E=N/M
3 F=C-E

Очевидно, что 1я и 2я операция не зависят друг от друга и их можно выполнить одновременно, а уж потом только 3ю операцию. Ещё пример
1 С=A+B
2 E=С/А
3 F=М-N

Здесь ещё интересней: одновременно можно выполнить 1ю и 3ю операцию и только потом 2ю, т.к. она зависит от 1й. Таким образом, мы получаем внеочередное исполнение команд или Суперскалярность. Теперь давайте посмотрим, как же этот принцип реализуется, но для начала посмотрим упрощённую структуру не суперсколярного процессора.


не суперскалярный процессор

Назначение Кешей L1 и L2 мы уже выяснили, хотя следует обратить на одну деталь: Кеш L1 для данных и для инструкций раздельный, просто так удобнее организовать работу процессора. Декодер необходим, чтобы перевести программный код стандартный для всех х86 процессоров в индивидуальный код данного процессора. Поясню подробнее: для выполнения какой либо операции необходимо в функциональном устройстве выполнить несколько операций: где-то что-то записать в какой либо регистр, перевести АЛУ (арифметико-логическое устройство, ALU, Arithmetic Logic Unit) в тот или иной режим и т. д. В каждом процессоре внутренние команды МОПы могут быть разные, но на вход поступают стандартные х86 инструкции, поэтому декодер просто необходим. Теперь рассмотрим суперскалярную архитектуру.


суперскалярный процессор

Здесь имеется N штук декодеров и М штук функциональных устройств. Декодеры преобразуют инструкции в МОПы. Эти МОПы поступают в буфер МОПов, где они дожидаются своего исполнения. Как только будут известны и загружены все операнды, и будет свободное функциональное устройство, операция будет выполнена в функциональном устройстве, а соответствующий ей МОП будет удалён из буфера МОПов.

При исполнении программного кода практически никогда не бывает ситуации, чтобы были задействованы все (или хотя бы большинство) исполнительных блоков процессора. Как правило, в среднем при работе процессора задействуется лишь треть доступных вычислительных ресурсов (оценка Intel), что, согласитесь, не рационально. Соответственно, возникла следующая мысль: если часть вычислительных блоков не занята текущей, исполняющейся в данный момент программой, нельзя ли их использовать для выполнения другой программы (либо другой нити этой же программы) в этот же момент времени? Так появилась технология Hyper Threading, используемая в П4 и представляющая одно физическое ядро как 2 логических. К сожалению, иногда получалось так, что при выполнении 2х процессов параллельно в 1 ядре уходило больше времени, чем, если бы эти процессы выполнялись последовательно. Виной тому был длинный конвейер П4 и Replay, которые загубили достаточно интересную технологию.

Когда потенциал одного ядра был исчерпан, инженерам пришла мысль сделать 2 ядра. Так появились у нас 2х ядерные процессоры, а потом появились и 4х ядерные процессоры.

Рассказ был бы неполным, если бы я не упомянул ещё о нескольких улучшениях. Во-первых, процессоры постепенно увеличивали свою разрядность. Само по себе увеличение разрядности не даёт увеличение производительности, большая разрядность даёт большую точность, но если надо выполнить операцию с большим количеством разрядов, то она разбивается на 2 операции: со старшей половиной и с младшей. Таким образом, увеличение разрядности всё-таки даёт небольшое увеличение производительности в некоторых приложениях. Современные процессоры 32х разрядные, хотя и считаются 64х битными, тем не менее, они полностью совместимы с 32х битными командами. Их 64х битность заключается в том, что некоторые регистры 64х битные и некоторые операции могут выполняться в 64х битном эквиваленте. В большинстве же приложений достаточно 32х бит.

Во-вторых, процессоры постоянно дополняются наборами команд. Одними из таких команд стали команды, которые позволяют работать с векторами: SSE, 3DNOW!

В общем, то на этом можно было бы закончить моё повествование, но пришла мне тут одна мысль, когда я смотрел на микроархитектуру Conroe.


структурная схема Conroe

Так вот данный процессор имеет 2 ядра, в каждом из которых 4 декодера, 3 АLU, 1 FPU (устройства работы с числами с плавающей запитой, когда-то был отдельный чип - сопроцессор), емкость буфера МОПов 96 микроопераций. Причём оба ядра находятся на одном кристалле. А что если сделать 1 ядро с 6 АLU, 2 FPU, емкость буфера МОПов 2*96=192 с технологией Hyper Threading. Стоп стоп, не надо меня кидать тухлые помидоры и яйца. Все конечно знают, что лучше 2 натуральных ядра, чем 2 логических, но для начала выслушайте мой идею. Во-первых, достаточна хорошая идея Hyper Threading была убита длинным конвейером П4, во-вторых, взгляните на рисунок:


структурная схема процессора, которую предлагаю я

Итак, у нас остаётся то же количество транзисторов, а значит то же тепловыделение и та же частота. Теперь посмотрим, что это нам даст:
1.Допустим, мы имеем 2 одинаковых потока. В этом случае наш процессор будет работать, так же как и 2х ядерный, т.е. каждому потоку будет отведены те же ресурсы.
2.Теперь предположим, что у нас имеется 1 поток, который преимущественно целочисленные операции, а второй поток использует операции с плавающей запетой. В случае 2х ядер у нас на первый поток будет 3 ALU, а на 2й 1 FPU. В случае же объедения ядер мы получим для первого процесса 6 АLU и 2 FPU для 2го, т.е. практически 2х кратный выигрыш и это при том же количестве транзисторов!
3.Допустим у нас 1 поток, тогда этому потоку будет предоставляться гораздо большие вычислительные и прочие ресурсы. Далеко не все процессы могут распараллеливаться на 2 ядра, так давайте же делать их в одном, но более мощном.
Теперь о недостатках. Я лично насчитал 3:
1.Маркетинговый – все знают, что 2 ядра лучше одного. К тому же не всем нравится Hyper Threading. О преимуществах я рассказал, поэтому думаю, что тесты смогут подтвердить выигрыш от этой архитектуры, да и маркетологи выкрутятся, не такое впихивали (представляю их лозунг: 1 умный лучше 2х дураков )
2.Объединение 2х кешей L1 может увеличить увеличение их латентности (задержки). Возможно, для каждого потока придётся делать свой Кеш. В принципе Я не думаю, что это серьёзно уменьшит производительность.
3.Трудность объединять 4 ядра или делать одноядерные не объединенные. Дело в том, что все блоки должны быть на одном кристалле. В общем-то сейчас, как Интел, так и АМД разрабатывают 4х ядерные процессоры на одном кристалле. По поводу уменьшения производительности для бюджетных систем я вижу следующий выход, делать в них меньше блоков. Допустим, так уже давно поступает, при изготовлении видеокарт среднего и низшего ценового диапазона. Просто берут ту же архитектуру что и в топе и делают меньше блоков.

Используемая литература:
1.http://www.overclockers.ru/lab/15496.shtml
2.http://www.fcenter.ru/online.shtml?articles/hardware/processors/11103 4 части.
3.http://www.fcenter.ru/online.shtml?articles/hardware/processors/12033 Replay.
4.http://www.3dnews.ru/cpu/new_core_conroe/
5.http://www.ixbt.com/cpu/cpu-microarchitecture-part-1.shtml 3 части.
6.Вообще я перекопал намного больше, просто всего не вспомню, также я использовал личные знания по технике, полученные в институте, как – никак на радиоинженера учусь.

обсудить, сделать замечания, спрость интересующие вас вопросы можно тут
http://forums.overclockers.ru/viewtopic.php?p=4069349#4069349
Telegram-канал @overclockers_news - это удобный способ следить за новыми материалами на сайте. С картинками, расширенными описаниями и без рекламы.
Оценитe материал

Возможно вас заинтересует

Популярные новости

Сейчас обсуждают