Разделение очень условное — чёткой границы меж способами увеличения производительности нет, ну и снутри себя они тоже делятся на различные подклассы. Т.к. за обработку данных отвечает один либо несколько центральных процессоров (ЦП), а производительность является его/их главной чертой — большая часть методов так либо по другому касаются конкретно данной части системы. Заблаговременно предупредим, что под процессором мы осознаем микросхему с корпусом и выводами, вставленную в разъём (сокет). Для ускорения таковых систем применяется два метода — численно прирастить число узлов (вплоть до 10-ов тыщ) и ускорять сами узлы. Уже по цифрам видно, что для суперкомпьютеров 1-ый метод — основной, но жрущие мегаватты и шумящие вентиляторами шкафы домашнему юзеру не подходят. Так что более принципиальной задачей будет ускорение системы, не приводящее к линейному повышению её физических размеров. Самый тривиальный (количественный) метод — нарастить число ЦП в пределах системного блока и платы. Отменно же (так как это труднее) требуется увеличивать число вычислительных ядер снутри 1-го ЦП — что активно происходит и в индивидуальных компах. Увеличивать можно, устанавливая несколько 1-ядерных чипов в один корпус, либо делая чип с несколькими ядрами. Возможны и композиции — 4-ядерные ЦП Intel Core 2 Quad имеют два 2-ядерных чипа. Наиболее тесное размещение ядер имеет плюсы и минусы. Плюсы — умещается больше ядер на единицу физического объёма системы, возможен стремительный обмен данными меж ядрами через внутрипроцессорные шины и общую кэш-память. Недочеты — у ядер есть общие конкурентно разделяемые ресурсы (кэши, контроллёры шин и памяти), многоядерные ЦП больше потребляют энергии и больше нагреваются (а отвести сотки ватт с микросхемы — дело сложное, в особенности, когда процессоров несколько), у однокристальных многоядерных ЦП меньше частотный потолок (наибольшая частота, на которой надёжно заработает самая стремительная микросхема посреди всех для себя схожих) из-за отсутствия способности согласовать свойства пары ядер (а вот отдельные чипы согласовать можно). Невзирая на трудности, количественное усиление характеристик системы размножением её компонентов практикуется издавна: есть RAID-массивы для винчестеров, 2-3 видеокарты в одной упряжке и многомониторные конфигурации, 2-3-канальные контроллёры памяти — уместно добавить сюда и пару многоядерных процессоров. 1-ое разделение относится к числу процессоров: высококачественные способы подразумевают ускорение работы ЦП при постоянном его/их количестве, количественные — наращивание числа ЦП с целью сложить их усилия. Многопроцессорные архитектуры используются, когда остальные методы уже внедрены и поболее не эффективны, и при должном умении инженеров и программистов дают хороший итог (ежели, естественно, задачка отлично распараллеливается) — совокупная производительность системы растёт практически линейно числу процессоров благодаря кропотливо слаженной синхронизации взаимодействий вычислительных узлов. В крайних выпусках рейтинга самых стремительных суперкомпьютеров планетки Top500 практически все машинки употребляют кластерную архитектуру, основанную на концепции массового параллелизма (MPP, massively parallel processing). В этих вычислительных чудовищах, занимающих целые залы, сразу работают 10-ки, а скоро, может быть, и сотки тыщ процессоров. Но не любая программа, в особенности домашней неспециализированной направленности, отлично распараллеливается на несколько потоков, задействуя все имеющиеся ядра. До этого времени почти все игры (а из фаворитных программ конкретно они самые ресурсоёмкие) практически не ускоряются при числе ядер выше 2-ух, не говоря уже о линейном увеличении производительности при большем их числе. Так что ускорение самого ядра непременно, в особенности, ежели оно одно. Эта самая задачка является самой сложной. Уже в первых вычислительных системах сходу опосля возникновения стали использовать разнообразые методы, о которых пойдёт речь дальше — путь был длинный. И здесь опять необходимо разделение на количественное и высококачественное улучшение. К количественному отнесём повышение частоты ЦП, как его главной числовой свойства («брали мгц» ещё в 80-х), а к высококачественному — число выполненных действий за каждый такт. Повышение частоты достижимо 2-мя методами. На физическом уровне: понижая проектные нормы, т.е. малые размеры проводников и транзисторов на чипе — за счёт этого крайние работают скорее и потребляют меньше энергии (это основная причина, почему в своё время мир отказался от ТТЛ - и ЭСЛ-семейств логики в пользу КМОП — у тех при уменьшении размеров таковых масштабных приемуществ не было). И архитектурно: увеличивая частотный потолок разделением процессора на отдельные стадии, т.е. организацией вычислительного конвейера. А ежели он уже есть — повышением числа этих стадий. Вычислительный конвейер в однокорпусных процессорах (а ранее — в огромных ЭВМ, где ЦП состоял из 10-ов микросхем) устроен так же. Его можно убыстрить, разделив на стадии, но чтоб нормально применять транзисторы (при данном техпроцессе их число больше остальных причин влияет на стоимость), стадии должны работать с очень близким темпом. Потому, удвоив число стадий, новейший ЦП на том же техпроцессе может поднять частотный потолок наименее чем в два раза (ежели удвоение привело к неравномерной разбивке), наиболее чем в два раза (см. пример со станками) либо ровно в два раза (ежели всё было и осталось отменно разбито). Но процесс обработки команд и данных нельзя «нашинковать» в случайных местах на хоть какое число кусков (хотя создатели крайних модификаций Pentium 4 сделали такую попытку, получив в итоге чрезвычайно горячий и частотный, но равномерно производительный процессор). Но основное — длиннющий конвейер панически опасается условных переходов. Разглядим для примера заводик, выпускающий некоторую деталь. Пока на нём 1 станок, обрабатывающий заготовку за 6 минут. Производительность — 10 деталей/час. Но процесс можно поделить на 3 отдельных почти не связанных шага, которые можно делать сразу над 3-мя деталями — любая на собственной стадии. Ставим три станка заместо 1-го: 1-ый над каждой деталью работает 1 минутку, 2-ой 3 и 3-ий 2. Общественная производительность конвейера ограничивается самой медленной его частью — вторым станком. И хотя другие нередко простаивают, наш заводик выпускает уже 20 деталей/час. Чтоб улучшить конвейер, следует сделать работу его стадий очень равномерной — передать часть работы со второго станка на 1-ый так, чтоб оба работали за 2 минутки. Но это не постоянно выходит, зато находится, что мы можем самую медленную часть системы («бутылочное горлышко») поделить на 2 шага — пускай по 1 и 2 минутки каждый. Сейчас у нас 4 станка с темпом работы 1, 1, 2 и 2 мин., соответственно. Всё бы отлично, но количество железа возросло в четыре раза, а вот скорость работы — всего в три раза. А не порезать ли нам конвейер ещё помельче — поставим 6 станков, работающих по одной минутке. Сейчас мы затратили 6-кратное количество средств производства и получили 6-кратный выход продукта. При появлении в програмке хоть какого ветвления (что, по статистике, происходит каждые 7-10 команд) особая схема (предсказатель переходов, 1-ая стадия конвейера) обязана за 1 такт «сообразить», сработает ли этот переход, и, ежели да, то куда — при том, что данные для вычисления управляющего условия могут быть не готовы. Безусловные переходы, вызовы и возвраты функций (не считая косвенных) требуют лишь предсказание мотивированного адреса, а для условных переходов нужно предсказать и поведение. Хотя современные методы динамических предсказателей успешны на 98-99 % (1-2 % ошибок), и это неидеально. Допустим, что предсказатель 20-стадийного конвейера ЦП имеет удачливость 98%, а условные переходы встречаются каждые 10 команд, причём сами команды в среднем выполняются за полтакта, т.к. процессор суперскалярный (см. дальше). Любая 50-я команда перехода будет ошибочно предсказана — 1 раз в 250 тактов придётся перегружать конвейер, очищая его от 20 накопившихся с неправильной ветки команд. Таковым образом, на каждые 270 тактов 20 мы выбрасываем впустую, снижая производительность на 7,4%. Необходимо удвоить частотный потолок, удвоив число стадий конвейера — нет заморочек, но готовимся к двойным штрафам (в тактах) за ошибочно предсказанные переходы. Либо придётся сделать лучше предсказатель, что непросто, т.к. его рабочие таблицы и логика занимают много места, что опять приводит к повышению стоимости (а она и так выросла от разбивки конвейера на маленькие стадии). Очевидно, можно разрубить гордиев узел одним махом — ежели не убрать условные переходы вообщем, то минимизировать их количество, а те, что остались — сделать очень прогнозируемыми. Делается это как алгоритмически (т.е. зависит от мудрости создателей компиляторов и обычных библиотек), так и архитектурно — в том же Pentium 4 внедрены особые префиксы-подсказки (которые сущность старенькые префиксы, игнорирующиеся перед командой перехода в ранешних ЦП). Префиксы ставятся профайлером (модуль среды программирования для оценки времени выполнения и использования ресурсов) и намекаюn предсказателю на вероятное поведение этого перехода как минимум на 1-ые несколько его выполнений (пока не накопится статистика срабатываний). Правда, в последующих архитектурах Intel и в любом процессоре AMD эти подсказки не действуют — очень неточно. Можно вспомнить, что ещё с 80-х возникли команды условного выполнения (установки константы и копирования значения), которые срабатывают лишь при «правильных» флагах. Всё это активно применяется и на данный момент — тем более, резвого роста числа стадий конвейера со времён забвения Pentium 4 не наблюдается ни у 1-го производителя ЦП. Итак, частотный потолок возрастает тяжело. При всем этом б Вообщем, 10 и поболее стадий мы бы не узрели ни в каком процессоре, если б не прозорливое решение Intel скооперировать жеребца и трепетную лань — скорую, но сложную для программирования строительную модель RISC с комфортной, но медленной парадигмой CISC. Получившийся процессор, а это был Pentium Pro, имел внутренний декодер, транслирующий внешнюю CISC-команду набора x86 в одну либо несколько внутренних RISC-подобных микроопераций (мопов) — они и путешествуют дальше по конвейеру до выполнения. (Справедливости ради — в 1994 г., за год до PPro вышел NexGen Nx586 с практически таковым же внутренним устройством, после этого NexGen была куплена AMD, и через 2 года вышел 1-ый K5.) Наиболее обыкновенные команды проще подготавливать и исполнять, но их самих требуется больше для реализации метода. Тем более, получаемое частотное ускорение того стоит, хотя таковой шаг можно сделать только раз: предстоящее разбиение мопов на ещё наиболее обыкновенные операции уже нереально, потому это улучшение высококачественное, а не количественное. о льшая частота просит большего напряжения питания, что наращивает потребление энергии приблизительно в 5 раз на каждое удвоение частоты. (Безупречный полевой транзистор имеет линейную зависимость макс. частоты от напряжения питания, линейную зависимость энергопотребления от частоты и квадратичную — энергопотребления от напряжения, получая 8-кратное повышение употребления и выделения ватт при удвоении герц. Но паразитные ёмкости, утечки тока и остальные неидеальности делают зависимость сглаженной в сторону квадратичной, а не кубической.) Возможность пожарить яичницу на радиаторе ЦП навряд ли будет оценена как принципиальное достоинство новейшего поколения процессоров, ну и мобильная электроника с её полной экономией на всём просит энергоэффективности не во вред скорости — нужно иметь методы убыстрить производительность при уже имеющейся частоте. Производительность за такт характеризуется 2-мя взаимно обратными величинами — среднее число тактов для выполнения одной команды (clocks per instruction, CPI) и среднее число выполненных за такт команд (instructions per clock, IPC). До возникновения суперскалярных ЦП основным методом ускорения кроме частотной гонки было уменьшение CPI (либо повышение IPC, хотя таковой термин ещё не применялся за ненадобностью). Это можно отвести к высококачественному улучшению, т.к. основной метод один — заместо размножения либо разгона имеющихся структур добавляются новейшие, аппаратно (т.е. скорее) вычисляющие то, что ранее неторопливо делалось в блоках общего назначения. заместо единой мультиплексированной шины для адресов и данных в 286 эти шины отдельные, что удвоило пропускную способность по данным; Для примера разглядим улучшения, позволившие 286-му процессору быть практически в два раза скорее 86-го по CPI, выполняя этот же код: декодер команд считывает не по одному, а по два б за такт — длинноватые команды декодируются скорее; регистровый файл (РФ) стал 2-портовым — за такт можно считать либо записать пару регистров, а копирование „регистр-регистр“ быть может изготовлено снутри самого РФ без использования наружного буфера; все операции сдвига делаются не в АЛУ с темпом 4 такта/бит, а в отдельном поочередном регистре сдвига с темпом 1 такт/бит; возникло AGU — устройство генерации адреса, адресный калькулятор для вычисления смещения в текущем секторе либо страничке с хоть каким видом адресации скорее вычисления адреса в общем АЛУ; возник отдельный счётчик для повторяющихся операций (сдвиг, строчки, многорегистровые операции со стеком); АЛУ имеет свой обычной регистр сдвига для хранения частичной суммы либо остатка, что в 5-7 раз ускорило умножение и деление. Когда практически любая команда выполняется за 1-2 такта, а все многофункциональные устройства (ФУ, специализирующиеся фактически исполнением команд) уже полноконвейерные, наступает шаг суперскалярности — роста числа самих конвейеров. Сейчас процессор может выполнить наиболее одной команды за такт (IPC>1). Как и внедрение и повышение буферов и кэшей, этот способ количественный. Казалось бы, увеличивай для себя конвейеры и наслаждайся высочайшей производительностью (во вред площади ЦП). Но на этом пути нас ждёт такое число подводных камешков, что становится ясно, почему переход на 2-путную суперскалярность (считая количество строительных, а не внутренних команд) произошёл в 1993 г. (Pentium), на 3-путную — в 1995 (Pentium Pro), а на 4-путную — лишь в 2006 (Core 2, AMD же лишь собирается в 2011). Дело в том, что сразу исполнять команды можно, лишь ежели они не конфликтуют: У 386-го процессора удвоили очередь предзагрузки команд (prefetch queue) до 12 б, расширили до 3 б разрядность декодера, добавили опосля него буфер микрокоманд (сейчас это ЦП с 3-стадийным конвейером), и заменили поочередный регистр сдвига параллельным (barrel shifter, производит хоть какой вид сдвига на хоть какое число бит за фиксированное время). 486-й наделён конвейерным исполнением, интегрированным вещественным блоком, буфером записи и внутренним кэшем L1 (тот, что на плате, сейчас L2). 486DX2 получил возможность кэшировать в L1 запись (write-back, не во всех моделях), а 486DX4 — двойной кэш и матричный умножитель (правда, пока лишь целочисленный и половинной разрядности — 16·16). Все подобные улучшения длятся до этого времени — к примеру, до возникновения архитектур AMD К10 и Intel Core 2 процессоры делали арифметические команды над векторными вещественными данными с темпом 2 такта — векторные АЛУ и умножители там половинной, 64-битной ширины, а у К10 и Core 2 они стали полноразрядными. по трудности (декодеру не хватит наибольшего числа мопов, генерируемых за такт); и пр.. Основной таковой костыль — внеочередное выполнение (Out-of-order execution, OoOE либо OOO): мопы скапливаются в особом перетасовочном буфере (reorder buffer, ROB) и считываются оттуда уже не в указанном програмкой порядке, а в случайном при возникновении способности одновременного выполнения. Т.к. буфер вмещает 10-ки мопов, этого хватит на 3-4 запускаемые за такт команды, даже далековато стоящие друг от друга (ежели они уже считаны и декодированы). В особенности отлично OOO работает с ещё одним механизмом улучшения — переименование регистров удаляет ложные взаимозависимости по операндам следующих команд от прошлых. Но и это пока не дозволяет поднять IPC выше 4-х. Частично поэтому, что мопов больше, чем команд, так что считывая 4 команды, мы получаем 5-10 мопов, для хранения и выполнения которых будет нужно такое же количество вольных ресурсов каждый такт. Потому придумана схема слияния (fusion), позволяющая объединять на время подготовительной подготовки пару команд (пока пару, но полностью может быть, что больше ни у кого не получится). Для мопов это микрослияние: декодер генерирует слитые мопы, которые при распределении запускаются в пару различных ФУ, выполняя там различные операции, что экономит число занятых мопами конвейерных шин и ячеек буферов. Для наружных команд это макрослияние: декодер трактует некие пары команд как одну, генерируя для неё 1 моп (может быть, тоже слитый), что в редких вариантах также поднимает IPC. Но самое основное — в програмке могут практически не встречаться длинноватые цепочки команд, параллельно выполнимые даже на безупречном процессоре. В итоге уже для перехода к трём конвейерам потребуются высококачественные «подпорки» для наибольшего наполнения конвейеров командами. Да и эти способы недостаточны, когда происходят такие рушащие производительность действия, как ошибочно предсказанный переход, кэш-промах (запрошенная информация не закэширована), долго исполняющаяся команда и т.п.. — при заторе в одной стадии другие ожидают, пока подходящий ресурс станет легкодоступным. Тогда меж стадиями добавляют бессчетные буферы и очереди, сглаживающие разницу в производительности отдельных шагов и поддерживающие на плаву весь конвейер 1-ые несколько тактов опосля фатального затора. А далее всё равно нужно откуда-то брать команды и данные. И ежели с текущей програмкой мы ничего сделать не сможем, пока не рассосётся затор, — может, переключимся на другую, раз уж все процессоры многозадачные? Родилась мысль одновременной многопоточности (simultaneous multithreading либо SMT, по терминологии Интел — гиперпоточность, hyper-threading/HT) либо виртуальной многоядерности. Каждое физическое ядро представляется системе как несколько логических, хотя практически все ресурсы в их являются разделяемыми (не считая строительного РФ, стека адресов возврата и неких остальных блоков памяти, неповторимых для каждого потока). При заторе в одном потоке ЦП может быстро всем конвейером переключиться на выполнение последующего сразу с подкачкой подходящего ресурса — при возврате в 1-ый поток там уже будет всё готово. В случае плавного выполнения всех потоков переключение меж ними происходит как при обыкновенной многозадачности — программно, через интервалы и в зависимости от приоритета задачки. Но ещё лучше переключаться не многим конвейером, а отдельными вольными стадиями (конкретно это и предполагается в SMT). Допустим, в двухпоточном ЦП буфер мопов опосля декодера оказался заполнен — тогда предсказатель переходов, загрузчик команд и декодер (т.е. все стадии до буфера) переключаются на иной поток, заполняя его мопами или отведённую для этого потока половину буфера, или динамически „отнимая“ от первого потока часть места для второго. Суперскалярные процессоры могут также сразу запускать на выполнение (в т.ч. внеочерёдное) мопы различных потоков и вперемешку считывать для их данные из кэша. Наиболее того, т.н. барабанный процессор (barrel processor, который, может быть, будет реализован в будущей архитектуре AMD Bulldozer) вообщем может переключаться на последующий поток каждый такт всеми стадиями конвейеров (не считая занятых наиболее 1-го такта) вне зависимости от того, произошёл ли в течение этого такта затор либо нет. — прирастить разрядность обрабатываемых данных до 32-х бит (количественное решение). Но для целых чисел больше, обычно, не нужно (не считая вычисления адресов для 64-битного режима), для вещественных 64 бита двойной точности тоже издавна достигнуты, так что повышение разрядности значит переход к векторным вычислениям (согласно парадигме SIMD — одна команда, много данных) и повышение числа компонент вектора. До этого времени большая часть процессоров (не только лишь x86) обходились 128-битными векторами, куда умещается пара вещественных чисел двойной точности либо целых 64-битных (раз уж ЦП таки перебежали на 64-битные вычисления спустя практически 20 лет опосля перехода на 32 бита), или 4 32-битных значения (целых либо одинарных вещественных). Intel в первый раз встроила векторные ФУ сходу в ЦП (заместо возможного векторного сопроцессора), хотя они поначалу были 64-битные (целочисленная разработка MMX, а ещё ранее, в 1989 г. — аналогичное векторное ФУ для RISC-ЦП i860). В ближайшее время внедрение остальных методов убыстрить ЦП очень усложнилось, так что Intel опять дает прирастить разрядность векторов — в два раза в наборе команд AVX для ЦП общего назначения, а в особом (но тоже x86-совместимом) процессоре Larrabee — даже в четыре раза (до 512 бит), оставляя место и для дальнейших расширений. Вспоминается судьба японских суперкомпьютеров NEC серии SX, считающих векторами по 8 компонент (512 бит) и проигрывающих по пиковой производительности многоузловым кластерным системам традиционной «настольной» архитектуры за ту же стоимость — с несколькими многоядерными ЦП в узле, любой из которых обрабатывает 128-битные векторы. Вообщем, OOO и SMT не могут поднять производительность выше пиковой, определяемой числом конвейеров (уровнем суперскалярности) и скоростью срабатывания ФУ — они только нивелируют неизбежные заторы команд и данных, понижая простои и очень загружая ресурсы. Чтоб повысить скорость ещё, требуется что-то сделать не на уровне команд, а на уровне обрабатываемых ими данных. 1-ое, что пришло бы в голову, Единственный высококачественный метод убыстрить обработку данных при фиксированном числе команд — внедрять новейшие команды, исполняющие над данными больше действий, заменяя несколько (время от времени даже 10-ов) обычных инструкций. Это не только лишь уменьшает размер кода, да и ускоряет его, т.к. выполнение новейшей команды будет быстрее аппаратное, а не микропрограммное. Вот примеры: операции с битами и битовыми полями (поиск, подборка, вставка и подмена); условные операции (копирование, запись константы); операции с конфигурацией формата на лету (расширение нулём и знаком, перевод из вещественных в целые либо обратно, изменение точности, маскированная запись); многоразрядные операции с переносом (для наращивания размера обрабатываемых данных, ежели они не умещаются в одном регистре); команды с регулировкой точности (умножение с получением лишь старшей либо младшей половины результата, приближённые вещественные вычисления и повышение их точности аппроксимацией); программно-специфичные команды (подсчёт контрольной суммы и битовой населённости, поиск подстроки, сумма модулей разностей, индекс и значение минимума в векторе, скалярное произведение). слитые команды (умножение-сложение, сложение-вычитание, сравнение-обмен, синус-косинус, перетасовка компонентов вектора, минимум, максимум, среднее, модуль, символ); По числу пт выше видно, что добавление доп наборов команд — один из главных способов ускорения ЦП. Уже на данный момент общее число команд в архитектуре x86 перевалило за 1000, что привело к исключительному усложнению декодеров и ФУ, также к сильному затруднению программирования и оптимизации на ассемблере. Тем более, Intel (а конкретно она ввела подавляющее большая часть таковых наборов) продолжает снабжать новейшие процессоры очередными видами инструкций, заставляя то же самое делать и соперника. Предсказать ветвления технической мысли инженеров, архитекторов и микроэлектронщиков, пытающихся отыскать очередной метод убыстрить процессор — задачка не проще, чем самому ЦП предсказать ветвления в исполняемой програмке с 99%-ной точностью. Тем более, ежели поглядеть с высоты на историю способов ускорения вычислений, замечается любознательная закономерность: поначалу некоторый метод возникает в огромных машинках — мэйнфреймах и суперкомпьютерах, где он проверяется и оттачивается. Потом, благодаря прогрессу в микроэлектронике, то, что ранее занимало шкафы и залы, стало вероятным уместить на одну плату, позже в корпус процессора, а потом и на его чип. Конвейеры, кэши, суперскалярность, ОOО, SIMD и остальное — всё это родом из 60-80-х. Нужно считать, что схожее будет происходить и дальше — просто поглядим на нынешние суперкомпьютеры и попытаемся через 10-20 лет сделать то же самое в одной микросхеме. Но здесь ждёт неожиданная развязка — большая часть мощнейших компов планетки сейчас сами основаны на архитектуре x86. Просто она оказалось настолько удачной и всепригодной, так быстро вобрала в себя всё наилучшее от соперников, что, напротив, это суперкомпьютеры сейчас делаются на архитектуре, вначале предназначенной для персоналок. Практически, вычислительная техника, сделав полный круг, упёрлась сама в себя. Вообщем, рост может не пригодиться. Как произнес в 90-х один юзер, имевший отношение к ВПК, «моего компа с 486-м процессором с головой хватило бы для управления всей группировкой русских военных спутников, но его не хватает на одновременный набор и распечатку текста в Word'е». 10-ки гигафлопов и доступность программирования на языках высочайшего уровня, скрывающих сложность аппаратных тонкостей, так развратили почти всех программистов, что они и мыслить закончили о некий там экономии и оптимизации — для чего, ежели юзер просто подождёт полгода и проапгрейдится, а за это время лучше не улучшить текущую версию программы, а сделать новейшую и реализовать её подороже. Когда программирование из творчества перевоплотился в поточное ремесло (массовый ПК предполагает общее ПО и массового программера), главными стали не качество, скорость и удобство, а методы побыстрее заработать средства. Выходит, что опосля внедрения всех относительно обычных и дешевых ускорителей производительности основным методом сделать комп ещё скорее может оказаться оптимизация программ и экономия уже имеющихся ресурсов. Но это уже тема иной статьи. Может быть, спасением будет новенькая, некремниевая микроэлектроника (вообще-то, она уже издавна «нано-») — или углеродная на графене и нанотрубках, или квантовая на спинтронных транзисторах либо «запутанных» частичках. А может, и без электро энергии вообщем — фотоника активно изучается той же Intel, которая уже достигнула сотворения интегральных волноводов и изучит способы сотворения фотонного транзистора. Всё это способно поднять частотный потолок (ведь отрешаться от идеи синхронных вычислителей не собираются, хотя, к примеру, человечий мозг является «нетактируемой вычислительной машинкой»), а вот какие будут высококачественные идеи (кроме еще одного SSE8) — точно никто не знает. Потому несчастный закон Мура (который никакой не закон, а эмпирическая закономерность, не чрезвычайно чётко, но всё же соблюдающаяся в течение десятилетий) ближайшее время повсевременно подвергается сомнению — протянем ещё годков 5, либо наступит-таки конец экспоненциальному росту?
- Мультимедийный LCD-проектор Panasonic PT-LB55NTE
- Стали известны свойства 2-ух ультратонких ноутбуков HP Envy 13 и Envy 15
- Веб и сети: Desktop Orbiter v.4.2
- Gigabyte MA785GT-UD3H системная плата на чипсете AMD 785G (Socket AM3)
- Диспетчеры закачек: Internet Download Manager v.5.1.8 Build 2
- Ассортимент Panasonic пополнили два объектива эталона Micro Four Thirds (Микро 4/3)
- DRAM: трудности, которые мы избираем
- Sapphire Radeon HD 4890 Atomic — один из первых 3D-ускорителей, работающих на частоте 1 ГГц
- Двойное пополнение в рядах акустических систем с USB-подключением производства Altec Lansing
- Советы юзерам Mac OS X (часть 8)
- Обновление в каталоге мобильных устройств: 1-ая половина лета 2009 года
- Чистильщики: Norton Removal Tool (SymNRT) 2010 v.0.0.98
- iТоги 06.23: 1-ая неделька июня 2008
- Thermaltake анонсирует всепригодный процессорный кулер SpinQ VT
Разделение очень условное — чёткой границы меж способами увеличения производительности нет, ну и снутри себя они тоже делятся на различные подклассы. Т.к. за обработку данных отвечает один либо несколько центральных процессоров (ЦП), а производительность является его/их главной чертой — большая часть методов так либо по другому касаются конкретно данной части системы. Заблаговременно предупредим, что под процессором мы осознаем микросхему с корпусом и выводами, вставленную в разъём (сокет). Для ускорения таковых систем применяется два метода — численно прирастить число узлов (вплоть до 10-ов тыщ) и ускорять сами узлы. Уже по цифрам видно, что для суперкомпьютеров 1-ый метод — основной, но жрущие мегаватты и шумящие вентиляторами шкафы домашнему юзеру не подходят. Так что более принципиальной задачей будет ускорение системы, не приводящее к линейному повышению её физических размеров. Самый тривиальный (количественный) метод — нарастить число ЦП в пределах системного блока и платы. Отменно же (так как это труднее) требуется увеличивать число вычислительных ядер снутри 1-го ЦП — что активно происходит и в индивидуальных компах. Увеличивать можно, устанавливая несколько 1-ядерных чипов в один корпус, либо делая чип с несколькими ядрами. Возможны и композиции — 4-ядерные ЦП Intel Core 2 Quad имеют два 2-ядерных чипа. Наиболее тесное размещение ядер имеет плюсы и минусы. Плюсы — умещается больше ядер на единицу физического объёма системы, возможен стремительный обмен данными меж ядрами через внутрипроцессорные шины и общую кэш-память. Недочеты — у ядер есть общие конкурентно разделяемые ресурсы (кэши, контроллёры шин и памяти), многоядерные ЦП больше потребляют энергии и больше нагреваются (а отвести сотки ватт с микросхемы — дело сложное, в особенности, когда процессоров несколько), у однокристальных многоядерных ЦП меньше частотный потолок (наибольшая частота, на которой надёжно заработает самая стремительная микросхема посреди всех для себя схожих) из-за отсутствия способности согласовать свойства пары ядер (а вот отдельные чипы согласовать можно). Невзирая на трудности, количественное усиление характеристик системы размножением её компонентов практикуется издавна: есть RAID-массивы для винчестеров, 2-3 видеокарты в одной упряжке и многомониторные конфигурации, 2-3-канальные контроллёры памяти — уместно добавить сюда и пару многоядерных процессоров. 1-ое разделение относится к числу процессоров: высококачественные способы подразумевают ускорение работы ЦП при постоянном его/их количестве, количественные — наращивание числа ЦП с целью сложить их усилия. Многопроцессорные архитектуры используются, когда остальные методы уже внедрены и поболее не эффективны, и при должном умении инженеров и программистов дают хороший итог (ежели, естественно, задачка отлично распараллеливается) — совокупная производительность системы растёт практически линейно числу процессоров благодаря кропотливо слаженной синхронизации взаимодействий вычислительных узлов. В крайних выпусках рейтинга самых стремительных суперкомпьютеров планетки Top500 практически все машинки употребляют кластерную архитектуру, основанную на концепции массового параллелизма (MPP, massively parallel processing). В этих вычислительных чудовищах, занимающих целые залы, сразу работают 10-ки, а скоро, может быть, и сотки тыщ процессоров. Но не любая программа, в особенности домашней неспециализированной направленности, отлично распараллеливается на несколько потоков, задействуя все имеющиеся ядра. До этого времени почти все игры (а из фаворитных программ конкретно они самые ресурсоёмкие) практически не ускоряются при числе ядер выше 2-ух, не говоря уже о линейном увеличении производительности при большем их числе. Так что ускорение самого ядра непременно, в особенности, ежели оно одно. Эта самая задачка является самой сложной. Уже в первых вычислительных системах сходу опосля возникновения стали использовать разнообразые методы, о которых пойдёт речь дальше — путь был длинный. И здесь опять необходимо разделение на количественное и высококачественное улучшение. К количественному отнесём повышение частоты ЦП, как его главной числовой свойства («брали мгц» ещё в 80-х), а к высококачественному — число выполненных действий за каждый такт. Повышение частоты достижимо 2-мя методами. На физическом уровне: понижая проектные нормы, т.е. малые размеры проводников и транзисторов на чипе — за счёт этого крайние работают скорее и потребляют меньше энергии (это основная причина, почему в своё время мир отказался от ТТЛ - и ЭСЛ-семейств логики в пользу КМОП — у тех при уменьшении размеров таковых масштабных приемуществ не было). И архитектурно: увеличивая частотный потолок разделением процессора на отдельные стадии, т.е. организацией вычислительного конвейера. А ежели он уже есть — повышением числа этих стадий. Вычислительный конвейер в однокорпусных процессорах (а ранее — в огромных ЭВМ, где ЦП состоял из 10-ов микросхем) устроен так же. Его можно убыстрить, разделив на стадии, но чтоб нормально применять транзисторы (при данном техпроцессе их число больше остальных причин влияет на стоимость), стадии должны работать с очень близким темпом. Потому, удвоив число стадий, новейший ЦП на том же техпроцессе может поднять частотный потолок наименее чем в два раза (ежели удвоение привело к неравномерной разбивке), наиболее чем в два раза (см. пример со станками) либо ровно в два раза (ежели всё было и осталось отменно разбито). Но процесс обработки команд и данных нельзя «нашинковать» в случайных местах на хоть какое число кусков (хотя создатели крайних модификаций Pentium 4 сделали такую попытку, получив в итоге чрезвычайно горячий и частотный, но равномерно производительный процессор). Но основное — длиннющий конвейер панически опасается условных переходов. Разглядим для примера заводик, выпускающий некоторую деталь. Пока на нём 1 станок, обрабатывающий заготовку за 6 минут. Производительность — 10 деталей/час. Но процесс можно поделить на 3 отдельных почти не связанных шага, которые можно делать сразу над 3-мя деталями — любая на собственной стадии. Ставим три станка заместо 1-го: 1-ый над каждой деталью работает 1 минутку, 2-ой 3 и 3-ий 2. Общественная производительность конвейера ограничивается самой медленной его частью — вторым станком. И хотя другие нередко простаивают, наш заводик выпускает уже 20 деталей/час. Чтоб улучшить конвейер, следует сделать работу его стадий очень равномерной — передать часть работы со второго станка на 1-ый так, чтоб оба работали за 2 минутки. Но это не постоянно выходит, зато находится, что мы можем самую медленную часть системы («бутылочное горлышко») поделить на 2 шага — пускай по 1 и 2 минутки каждый. Сейчас у нас 4 станка с темпом работы 1, 1, 2 и 2 мин., соответственно. Всё бы отлично, но количество железа возросло в четыре раза, а вот скорость работы — всего в три раза. А не порезать ли нам конвейер ещё помельче — поставим 6 станков, работающих по одной минутке. Сейчас мы затратили 6-кратное количество средств производства и получили 6-кратный выход продукта. При появлении в програмке хоть какого ветвления (что, по статистике, происходит каждые 7-10 команд) особая схема (предсказатель переходов, 1-ая стадия конвейера) обязана за 1 такт «сообразить», сработает ли этот переход, и, ежели да, то куда — при том, что данные для вычисления управляющего условия могут быть не готовы. Безусловные переходы, вызовы и возвраты функций (не считая косвенных) требуют лишь предсказание мотивированного адреса, а для условных переходов нужно предсказать и поведение. Хотя современные методы динамических предсказателей успешны на 98-99 % (1-2 % ошибок), и это неидеально. Допустим, что предсказатель 20-стадийного конвейера ЦП имеет удачливость 98%, а условные переходы встречаются каждые 10 команд, причём сами команды в среднем выполняются за полтакта, т.к. процессор суперскалярный (см. дальше). Любая 50-я команда перехода будет ошибочно предсказана — 1 раз в 250 тактов придётся перегружать конвейер, очищая его от 20 накопившихся с неправильной ветки команд. Таковым образом, на каждые 270 тактов 20 мы выбрасываем впустую, снижая производительность на 7,4%. Необходимо удвоить частотный потолок, удвоив число стадий конвейера — нет заморочек, но готовимся к двойным штрафам (в тактах) за ошибочно предсказанные переходы. Либо придётся сделать лучше предсказатель, что непросто, т.к. его рабочие таблицы и логика занимают много места, что опять приводит к повышению стоимости (а она и так выросла от разбивки конвейера на маленькие стадии). Очевидно, можно разрубить гордиев узел одним махом — ежели не убрать условные переходы вообщем, то минимизировать их количество, а те, что остались — сделать очень прогнозируемыми. Делается это как алгоритмически (т.е. зависит от мудрости создателей компиляторов и обычных библиотек), так и архитектурно — в том же Pentium 4 внедрены особые префиксы-подсказки (которые сущность старенькые префиксы, игнорирующиеся перед командой перехода в ранешних ЦП). Префиксы ставятся профайлером (модуль среды программирования для оценки времени выполнения и использования ресурсов) и намекаюn предсказателю на вероятное поведение этого перехода как минимум на 1-ые несколько его выполнений (пока не накопится статистика срабатываний). Правда, в последующих архитектурах Intel и в любом процессоре AMD эти подсказки не действуют — очень неточно. Можно вспомнить, что ещё с 80-х возникли команды условного выполнения (установки константы и копирования значения), которые срабатывают лишь при «правильных» флагах. Всё это активно применяется и на данный момент — тем более, резвого роста числа стадий конвейера со времён забвения Pentium 4 не наблюдается ни у 1-го производителя ЦП. Итак, частотный потолок возрастает тяжело. При всем этом б Вообщем, 10 и поболее стадий мы бы не узрели ни в каком процессоре, если б не прозорливое решение Intel скооперировать жеребца и трепетную лань — скорую, но сложную для программирования строительную модель RISC с комфортной, но медленной парадигмой CISC. Получившийся процессор, а это был Pentium Pro, имел внутренний декодер, транслирующий внешнюю CISC-команду набора x86 в одну либо несколько внутренних RISC-подобных микроопераций (мопов) — они и путешествуют дальше по конвейеру до выполнения. (Справедливости ради — в 1994 г., за год до PPro вышел NexGen Nx586 с практически таковым же внутренним устройством, после этого NexGen была куплена AMD, и через 2 года вышел 1-ый K5.) Наиболее обыкновенные команды проще подготавливать и исполнять, но их самих требуется больше для реализации метода. Тем более, получаемое частотное ускорение того стоит, хотя таковой шаг можно сделать только раз: предстоящее разбиение мопов на ещё наиболее обыкновенные операции уже нереально, потому это улучшение высококачественное, а не количественное. о льшая частота просит большего напряжения питания, что наращивает потребление энергии приблизительно в 5 раз на каждое удвоение частоты. (Безупречный полевой транзистор имеет линейную зависимость макс. частоты от напряжения питания, линейную зависимость энергопотребления от частоты и квадратичную — энергопотребления от напряжения, получая 8-кратное повышение употребления и выделения ватт при удвоении герц. Но паразитные ёмкости, утечки тока и остальные неидеальности делают зависимость сглаженной в сторону квадратичной, а не кубической.) Возможность пожарить яичницу на радиаторе ЦП навряд ли будет оценена как принципиальное достоинство новейшего поколения процессоров, ну и мобильная электроника с её полной экономией на всём просит энергоэффективности не во вред скорости — нужно иметь методы убыстрить производительность при уже имеющейся частоте. Производительность за такт характеризуется 2-мя взаимно обратными величинами — среднее число тактов для выполнения одной команды (clocks per instruction, CPI) и среднее число выполненных за такт команд (instructions per clock, IPC). До возникновения суперскалярных ЦП основным методом ускорения кроме частотной гонки было уменьшение CPI (либо повышение IPC, хотя таковой термин ещё не применялся за ненадобностью). Это можно отвести к высококачественному улучшению, т.к. основной метод один — заместо размножения либо разгона имеющихся структур добавляются новейшие, аппаратно (т.е. скорее) вычисляющие то, что ранее неторопливо делалось в блоках общего назначения. заместо единой мультиплексированной шины для адресов и данных в 286 эти шины отдельные, что удвоило пропускную способность по данным; Для примера разглядим улучшения, позволившие 286-му процессору быть практически в два раза скорее 86-го по CPI, выполняя этот же код: декодер команд считывает не по одному, а по два б за такт — длинноватые команды декодируются скорее; регистровый файл (РФ) стал 2-портовым — за такт можно считать либо записать пару регистров, а копирование „регистр-регистр“ быть может изготовлено снутри самого РФ без использования наружного буфера; все операции сдвига делаются не в АЛУ с темпом 4 такта/бит, а в отдельном поочередном регистре сдвига с темпом 1 такт/бит; возникло AGU — устройство генерации адреса, адресный калькулятор для вычисления смещения в текущем секторе либо страничке с хоть каким видом адресации скорее вычисления адреса в общем АЛУ; возник отдельный счётчик для повторяющихся операций (сдвиг, строчки, многорегистровые операции со стеком); АЛУ имеет свой обычной регистр сдвига для хранения частичной суммы либо остатка, что в 5-7 раз ускорило умножение и деление. Когда практически любая команда выполняется за 1-2 такта, а все многофункциональные устройства (ФУ, специализирующиеся фактически исполнением команд) уже полноконвейерные, наступает шаг суперскалярности — роста числа самих конвейеров. Сейчас процессор может выполнить наиболее одной команды за такт (IPC>1). Как и внедрение и повышение буферов и кэшей, этот способ количественный. Казалось бы, увеличивай для себя конвейеры и наслаждайся высочайшей производительностью (во вред площади ЦП). Но на этом пути нас ждёт такое число подводных камешков, что становится ясно, почему переход на 2-путную суперскалярность (считая количество строительных, а не внутренних команд) произошёл в 1993 г. (Pentium), на 3-путную — в 1995 (Pentium Pro), а на 4-путную — лишь в 2006 (Core 2, AMD же лишь собирается в 2011). Дело в том, что сразу исполнять команды можно, лишь ежели они не конфликтуют: У 386-го процессора удвоили очередь предзагрузки команд (prefetch queue) до 12 б, расширили до 3 б разрядность декодера, добавили опосля него буфер микрокоманд (сейчас это ЦП с 3-стадийным конвейером), и заменили поочередный регистр сдвига параллельным (barrel shifter, производит хоть какой вид сдвига на хоть какое число бит за фиксированное время). 486-й наделён конвейерным исполнением, интегрированным вещественным блоком, буфером записи и внутренним кэшем L1 (тот, что на плате, сейчас L2). 486DX2 получил возможность кэшировать в L1 запись (write-back, не во всех моделях), а 486DX4 — двойной кэш и матричный умножитель (правда, пока лишь целочисленный и половинной разрядности — 16·16). Все подобные улучшения длятся до этого времени — к примеру, до возникновения архитектур AMD К10 и Intel Core 2 процессоры делали арифметические команды над векторными вещественными данными с темпом 2 такта — векторные АЛУ и умножители там половинной, 64-битной ширины, а у К10 и Core 2 они стали полноразрядными. по трудности (декодеру не хватит наибольшего числа мопов, генерируемых за такт); и пр.. Основной таковой костыль — внеочередное выполнение (Out-of-order execution, OoOE либо OOO): мопы скапливаются в особом перетасовочном буфере (reorder buffer, ROB) и считываются оттуда уже не в указанном програмкой порядке, а в случайном при возникновении способности одновременного выполнения. Т.к. буфер вмещает 10-ки мопов, этого хватит на 3-4 запускаемые за такт команды, даже далековато стоящие друг от друга (ежели они уже считаны и декодированы). В особенности отлично OOO работает с ещё одним механизмом улучшения — переименование регистров удаляет ложные взаимозависимости по операндам следующих команд от прошлых. Но и это пока не дозволяет поднять IPC выше 4-х. Частично поэтому, что мопов больше, чем команд, так что считывая 4 команды, мы получаем 5-10 мопов, для хранения и выполнения которых будет нужно такое же количество вольных ресурсов каждый такт. Потому придумана схема слияния (fusion), позволяющая объединять на время подготовительной подготовки пару команд (пока пару, но полностью может быть, что больше ни у кого не получится). Для мопов это микрослияние: декодер генерирует слитые мопы, которые при распределении запускаются в пару различных ФУ, выполняя там различные операции, что экономит число занятых мопами конвейерных шин и ячеек буферов. Для наружных команд это макрослияние: декодер трактует некие пары команд как одну, генерируя для неё 1 моп (может быть, тоже слитый), что в редких вариантах также поднимает IPC. Но самое основное — в програмке могут практически не встречаться длинноватые цепочки команд, параллельно выполнимые даже на безупречном процессоре. В итоге уже для перехода к трём конвейерам потребуются высококачественные «подпорки» для наибольшего наполнения конвейеров командами. Да и эти способы недостаточны, когда происходят такие рушащие производительность действия, как ошибочно предсказанный переход, кэш-промах (запрошенная информация не закэширована), долго исполняющаяся команда и т.п.. — при заторе в одной стадии другие ожидают, пока подходящий ресурс станет легкодоступным. Тогда меж стадиями добавляют бессчетные буферы и очереди, сглаживающие разницу в производительности отдельных шагов и поддерживающие на плаву весь конвейер 1-ые несколько тактов опосля фатального затора. А далее всё равно нужно откуда-то брать команды и данные. И ежели с текущей програмкой мы ничего сделать не сможем, пока не рассосётся затор, — может, переключимся на другую, раз уж все процессоры многозадачные? Родилась мысль одновременной многопоточности (simultaneous multithreading либо SMT, по терминологии Интел — гиперпоточность, hyper-threading/HT) либо виртуальной многоядерности. Каждое физическое ядро представляется системе как несколько логических, хотя практически все ресурсы в их являются разделяемыми (не считая строительного РФ, стека адресов возврата и неких остальных блоков памяти, неповторимых для каждого потока). При заторе в одном потоке ЦП может быстро всем конвейером переключиться на выполнение последующего сразу с подкачкой подходящего ресурса — при возврате в 1-ый поток там уже будет всё готово. В случае плавного выполнения всех потоков переключение меж ними происходит как при обыкновенной многозадачности — программно, через интервалы и в зависимости от приоритета задачки. Но ещё лучше переключаться не многим конвейером, а отдельными вольными стадиями (конкретно это и предполагается в SMT). Допустим, в двухпоточном ЦП буфер мопов опосля декодера оказался заполнен — тогда предсказатель переходов, загрузчик команд и декодер (т.е. все стадии до буфера) переключаются на иной поток, заполняя его мопами или отведённую для этого потока половину буфера, или динамически „отнимая“ от первого потока часть места для второго. Суперскалярные процессоры могут также сразу запускать на выполнение (в т.ч. внеочерёдное) мопы различных потоков и вперемешку считывать для их данные из кэша. Наиболее того, т.н. барабанный процессор (barrel processor, который, может быть, будет реализован в будущей архитектуре AMD Bulldozer) вообщем может переключаться на последующий поток каждый такт всеми стадиями конвейеров (не считая занятых наиболее 1-го такта) вне зависимости от того, произошёл ли в течение этого такта затор либо нет. — прирастить разрядность обрабатываемых данных до 32-х бит (количественное решение). Но для целых чисел больше, обычно, не нужно (не считая вычисления адресов для 64-битного режима), для вещественных 64 бита двойной точности тоже издавна достигнуты, так что повышение разрядности значит переход к векторным вычислениям (согласно парадигме SIMD — одна команда, много данных) и повышение числа компонент вектора. До этого времени большая часть процессоров (не только лишь x86) обходились 128-битными векторами, куда умещается пара вещественных чисел двойной точности либо целых 64-битных (раз уж ЦП таки перебежали на 64-битные вычисления спустя практически 20 лет опосля перехода на 32 бита), или 4 32-битных значения (целых либо одинарных вещественных). Intel в первый раз встроила векторные ФУ сходу в ЦП (заместо возможного векторного сопроцессора), хотя они поначалу были 64-битные (целочисленная разработка MMX, а ещё ранее, в 1989 г. — аналогичное векторное ФУ для RISC-ЦП i860). В ближайшее время внедрение остальных методов убыстрить ЦП очень усложнилось, так что Intel опять дает прирастить разрядность векторов — в два раза в наборе команд AVX для ЦП общего назначения, а в особом (но тоже x86-совместимом) процессоре Larrabee — даже в четыре раза (до 512 бит), оставляя место и для дальнейших расширений. Вспоминается судьба японских суперкомпьютеров NEC серии SX, считающих векторами по 8 компонент (512 бит) и проигрывающих по пиковой производительности многоузловым кластерным системам традиционной «настольной» архитектуры за ту же стоимость — с несколькими многоядерными ЦП в узле, любой из которых обрабатывает 128-битные векторы. Вообщем, OOO и SMT не могут поднять производительность выше пиковой, определяемой числом конвейеров (уровнем суперскалярности) и скоростью срабатывания ФУ — они только нивелируют неизбежные заторы команд и данных, понижая простои и очень загружая ресурсы. Чтоб повысить скорость ещё, требуется что-то сделать не на уровне команд, а на уровне обрабатываемых ими данных. 1-ое, что пришло бы в голову, Единственный высококачественный метод убыстрить обработку данных при фиксированном числе команд — внедрять новейшие команды, исполняющие над данными больше действий, заменяя несколько (время от времени даже 10-ов) обычных инструкций. Это не только лишь уменьшает размер кода, да и ускоряет его, т.к. выполнение новейшей команды будет быстрее аппаратное, а не микропрограммное. Вот примеры: операции с битами и битовыми полями (поиск, подборка, вставка и подмена); условные операции (копирование, запись константы); операции с конфигурацией формата на лету (расширение нулём и знаком, перевод из вещественных в целые либо обратно, изменение точности, маскированная запись); многоразрядные операции с переносом (для наращивания размера обрабатываемых данных, ежели они не умещаются в одном регистре); команды с регулировкой точности (умножение с получением лишь старшей либо младшей половины результата, приближённые вещественные вычисления и повышение их точности аппроксимацией); программно-специфичные команды (подсчёт контрольной суммы и битовой населённости, поиск подстроки, сумма модулей разностей, индекс и значение минимума в векторе, скалярное произведение). слитые команды (умножение-сложение, сложение-вычитание, сравнение-обмен, синус-косинус, перетасовка компонентов вектора, минимум, максимум, среднее, модуль, символ); По числу пт выше видно, что добавление доп наборов команд — один из главных способов ускорения ЦП. Уже на данный момент общее число команд в архитектуре x86 перевалило за 1000, что привело к исключительному усложнению декодеров и ФУ, также к сильному затруднению программирования и оптимизации на ассемблере. Тем более, Intel (а конкретно она ввела подавляющее большая часть таковых наборов) продолжает снабжать новейшие процессоры очередными видами инструкций, заставляя то же самое делать и соперника. Предсказать ветвления технической мысли инженеров, архитекторов и микроэлектронщиков, пытающихся отыскать очередной метод убыстрить процессор — задачка не проще, чем самому ЦП предсказать ветвления в исполняемой програмке с 99%-ной точностью. Тем более, ежели поглядеть с высоты на историю способов ускорения вычислений, замечается любознательная закономерность: поначалу некоторый метод возникает в огромных машинках — мэйнфреймах и суперкомпьютерах, где он проверяется и оттачивается. Потом, благодаря прогрессу в микроэлектронике, то, что ранее занимало шкафы и залы, стало вероятным уместить на одну плату, позже в корпус процессора, а потом и на его чип. Конвейеры, кэши, суперскалярность, ОOО, SIMD и остальное — всё это родом из 60-80-х. Нужно считать, что схожее будет происходить и дальше — просто поглядим на нынешние суперкомпьютеры и попытаемся через 10-20 лет сделать то же самое в одной микросхеме. Но здесь ждёт неожиданная развязка — большая часть мощнейших компов планетки сейчас сами основаны на архитектуре x86. Просто она оказалось настолько удачной и всепригодной, так быстро вобрала в себя всё наилучшее от соперников, что, напротив, это суперкомпьютеры сейчас делаются на архитектуре, вначале предназначенной для персоналок. Практически, вычислительная техника, сделав полный круг, упёрлась сама в себя. Вообщем, рост может не пригодиться. Как произнес в 90-х один юзер, имевший отношение к ВПК, «моего компа с 486-м процессором с головой хватило бы для управления всей группировкой русских военных спутников, но его не хватает на одновременный набор и распечатку текста в Word'е». 10-ки гигафлопов и доступность программирования на языках высочайшего уровня, скрывающих сложность аппаратных тонкостей, так развратили почти всех программистов, что они и мыслить закончили о некий там экономии и оптимизации — для чего, ежели юзер просто подождёт полгода и проапгрейдится, а за это время лучше не улучшить текущую версию программы, а сделать новейшую и реализовать её подороже. Когда программирование из творчества перевоплотился в поточное ремесло (массовый ПК предполагает общее ПО и массового программера), главными стали не качество, скорость и удобство, а методы побыстрее заработать средства. Выходит, что опосля внедрения всех относительно обычных и дешевых ускорителей производительности основным методом сделать комп ещё скорее может оказаться оптимизация программ и экономия уже имеющихся ресурсов. Но это уже тема иной статьи. Может быть, спасением будет новенькая, некремниевая микроэлектроника (вообще-то, она уже издавна «нано-») — или углеродная на графене и нанотрубках, или квантовая на спинтронных транзисторах либо «запутанных» частичках. А может, и без электро энергии вообщем — фотоника активно изучается той же Intel, которая уже достигнула сотворения интегральных волноводов и изучит способы сотворения фотонного транзистора. Всё это способно поднять частотный потолок (ведь отрешаться от идеи синхронных вычислителей не собираются, хотя, к примеру, человечий мозг является «нетактируемой вычислительной машинкой»), а вот какие будут высококачественные идеи (кроме еще одного SSE8) — точно никто не знает. Потому несчастный закон Мура (который никакой не закон, а эмпирическая закономерность, не чрезвычайно чётко, но всё же соблюдающаяся в течение десятилетий) ближайшее время повсевременно подвергается сомнению — протянем ещё годков 5, либо наступит-таки конец экспоненциальному росту?