Русский
Русский
English
Статистика
Реклама

Миран

Перевод FritzFrog новое поколение ботнетов

24.08.2020 18:21:28 | Автор: admin

Краткое содержание


  • Guardicore обнаружили сложный ботнет пиринговой (P2P) сети FritzFrog, который еще с января 2020 года активно взламывал SSH серверы.
  • Вредоносное ПО на Golang: FritzFrog исполняет модульный, мультипоточный и безфайловый вредоносный код на Golang, который не оставляет следов на жестком диске зараженного устройства.
  • Активное таргетирование государственных, образовательных, финансовых и прочих ресурсов: FritzFrog пытался брутфорсить и распространяться на десятках миллионов IP адресов правительственных офисов, образовательных учреждений, медицинских центров, банков и множества телекоммуникационных компаний. Среди них успешно подвержены атаке оказались более чем 500 серверов, включая известные университеты США и Европы, и одну железнодорожную компанию.
  • Сложность: FritzFrog полностью проприетарен, его имплементация P2P написана с нуля, что говорит о высоком уровне профессионализма его создателей в области разработки ПО.
  • Перехват: Guardcore Labs разработали клиентскую программу на Golang, способную перехватывать P2P соединения FritzFrog и подключаться к сети как пир.
  • Принадлежность: мы не смогли определить конкретную группу, ответственную за создание FritzFrog, однако текущий ботнет частично похож на ранее известный ботнет Rakos.

Введение


FritzFrog это очень изощренный пиринговый ботнет, который активно взламывает SSH серверы по всему миру. Благодаря своей децентрализованной структуре он распределяет контроль по всем своим узлам. В этой сети нет единой точки отказа, и пиры постоянно общаются друг с другом, чтобы поддерживать ее в устойчивом, обновляемом и постоянно активном состоянии. P2P соединение проводится через зашифрованный канал с использованием AES для симметричного шифрования и протокола Диффи-Хеллмана для обмена ключами.

В отличие от других P2P ботнетов, FritzFrog уникален набором своих свойств: он безфайловый, поскольку собирает и исполняет пакеты прямо в памяти; несмотря на эффективное равномерное распределение целей в своей сети, он очень агрессивно их брутфорсит; его проприетарные P2P протоколы не основаны ни на одной из ныне известных реализаций.

Написанный на Golang вредоносный код очень переменчив и не оставляет следов на жестком диске. Он создает бэкдор в виде публичного SSH ключа и тем самым открывает злоумышленникам постоянный доступ к устройству жертвы. С самого начала его активности мы выявили 20 различных версий исполняемого вредоносного ПО.

В этом посте мы расскажем, каким образом была раскрыта деятельность FritzFrog, а так же каковы природа его P2P сети и внутреннее устройство вредоносного кода включая процесс заражения, шифрование команд и изменчивое поведение.

Guardicore Labs предоставили доступ к Github репозиторию со скриптом для обнаружения этого вредоносного ПО и списком индикаторов компрометации (IoC) его деятельности.


Географическое распределение зараженных узлов. Наиболее подверженными атакам странами оказались США, Китай и Южная Корея.

Исследование FritzFrog


Впервые Guardcore Labs обратили внимание на деятельность FritzFrog в ходе исследования Botnet Encyclopedia. 9 января были обнаружены новые атаки с исполнением вредоносных процессов ifconfig и nginx. Мы начали отслеживать стабильный и значимый рост вредоносной деятельности, которая вскоре достигла 13 тысяч атак на Guardcore Global Sensors Network (GGSN). За все время мы отследили 20 различных версий бинарников FritzFrog.


График демонстрирует количество атак FritzFrog на GGSN.

Удивительным оказалось то, что вредоносный код на первый взгляд не связывался с каким-либо сервером командования и контроля (CNC). Только когда мы начали серьезно исследовать ботнет, мы поняли что никакого сервера не было и в помине.

Для перехвата сети ботнета Guardcore Labs разработали на Golang клиент, способный обмениваться ключами с вредоносным ПО, а так же отправлять команды и получать ответы. Эта программа, которую мы затем назвали фроггер, позволила нам исследовать природу и задачи сети, и благодаря фроггеру мы добавили в сеть наши собственные узлы, сумев подсоединиться к ботнету, и поучаствовали в передаче данных активного P2P трафика.

FritzFrog брутфорсил миллионы IP адресов, среди которых оказались правительственные офисы, образовательные учреждения, медицинские центры, банки и множество телекоммуникационных компаний. Из них успешно подвержены атаке оказались более чем 500 серверов, включая известные университеты США и Европы, и одну железнодорожную компанию.

Новое поколение P2P


Почему Новое поколение?


У FritzFrog есть уникальный набор свойств, который сильно выделяет его на фоне прочих сетевых угроз:

  • Безфайловость: FritzFrog работает без рабочей директории, а обмен файлами происходит прямо в памяти через массивы двоичных данных (BLOB).
  • Постоянные обновления: базы данных целей и пораженных устройств обновляются плавно и органично.
  • Агрессивность: брутфорс ведется с использованием обширного словаря. Для примера, недавно обнаруженный P2P ботнет DDG в поле логина использовал только root.
  • Эффективность: Цели равномерно распределены между узлами.
  • Проприетарность: P2P протокол ботнета полностью проприетарен и не основывается на каком-либо из известных P2P протоколов, например TP.

Как только жертва оказывается успешно взломана, на ней запускается UPX-запакованный вредоносный код, который затем тут же сам себя удаляет. Для минимизации подозрений вредоносные процессы исполняются под наименованиями ifconfig и nginx. В самом начале своей работы вредоносный код прослушивает порт 1234 в ожидании команд. Первые полученные команды синхронизируют жертву с базой данных пиров сети и целей брутфорса.


Кластер узлов сети FritzFrog. Каждый узел это зараженный SSH сервер. Размер узлов демонстрирует их связность с остальной сетью.

Трафик на нестандартном порте, например 1234, легко заметить и заблокировать файерволом либо любой другой системой защиты. Поэтому разработчики FritzFrog подошли к проблеме творчески и вместо прямой передачи команд через порт 1234 злоумышленник подключается к жертве через SSH и запускает на устройстве netcat клиент, который в свою очередь соединяется с сервером ботнета. Таким образом, любая команда будет передана через SSH как ввод netcat и без труда достигнет вредоносного кода.


FritzFrog туннелирует свои P2P команды через классический SSH порт, для чего пользуется локальным netcat клиентом зараженного устройства.

Злоумышленники FritzFrog внедрили зашифрованный командный канал с более чем 30 различными командами. Параметры команд и отклики передаются в указанных структурах данных и выпускаются (мобилизуются) в формате JSON. Перед отправлением данные зашифровываются симметричным шифрованием AES и кодируются в Base64. Для обмена ключами участвующие в передаче данных узлы используют протокол Диффи-Хеллмана.



Узлы в сети FritzFrog поддерживают тесный контакт, постоянно пингуя друг друга для проверки соединения, обмена пирами и целями и взаимной синхронизации. Узлы также участвуют в искусном избирательном процессе, который влияет на распределение целей брутфорса в сети. Наблюдения Guardcore Labs подтверждают, что цели в сети распределены равномерно и никакие два узла не будут пытаться взломать одну и ту же цель.

Погружение во вредоносный код


Бинарник FritzFrog это продвинутый вредоносный код на Golang. Он полностью работает в памяти, каждый узел с вредоносным кодом хранит в памяти всю базу данных целей и пиров. Вредоносный код создает несколько потоков для одновременной обработки различных задач в соответствии с приведенной ниже таблицей.

FritzFrog определяет состояния управления жертвой и целевым устройством следующим образом:
  1. Target (цель): устройство из запроса цели будет затем передано модулю Cracker, который в свою очередь постарается просканировать и взломать его.
  2. Deploy (развертывание): успешно взломанное устройство встает в очередь на заражение вредоносным кодом через модуль DeployMgmt.
  3. Owned (владение): успешно зараженное устройство будет добавлено в P2P сеть модулем Owned.




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


Рабочая функция в дизассемблере. Каждая ветка соответствует поддерживаемому P2P функционалу.

Вредоносный код несет временный характер: пусть он и пытается пережить системные перезагрузки, для будущего доступа к взломанной цели сохраняется бэкдор, чьи логин и пароль хранятся у пиров сети. Вредоносный код добавляет публичный SSH-RSA ключ в файл authorized_keys. Столь простой бэкдор позволяет злоумышленнику с секретным частым ключом аутентифицироваться без пароля, на случай если изначальный пароль оказался изменен. Единственный используемый FritzFrog публичный ключ приведен ниже.

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDJYZIsncBTFc+iCRHXkeGfFA67j+kUVf7h/IL+sh0RXJn7yDN0vEXz7ig73hC//2/71sND+x+Wu0zytQhZxrCPzimSyC8FJCRtcqDATSjvWsIoI4j/AJyKk5k3fCzjPex3moc48TEYiSbAgXYVQ62uNhx7ylug50nTcUH1BNKDiknXjnZfueiqAO1vcgNLH4qfqIj7WWXu8YgFJ9qwYmwbMm+S7jYYgCtD107bpSR7/WoXSr1/SJLGX6Hg1sTet2USiNevGbfqNzciNxOp08hHQIYp2W9sMuo02pXj9nEoiximR4gSKrNoVesqNZMcVA0Kku01uOuOBAOReN7KJQBt

Вредоносный файл прогоняет всевозможные команды оболочки на локальном устройстве, некоторые по несколько раз, для отслеживания состояния системы. Например, он прогоняет free m для проверки доступной оперативной памяти, uptime, journalctl s @0 u sshd для отслеживания SSH логинов, и прочие команды для вывода статистики нагрузки процессора. Эта статистика оказывается доступна другим узлам в сети, и используется для принятия различных решений, например запускать ли криптомайнер на устройстве или нет. Если решение принято, вредоносный код запускает отдельный процесс, libexec, для майнинга Monero. Этот майнер основан на популярном майнере XMRig и связывается с публичным пулом web.xmrpool.eu через порт 5555.

Злобная торрентоподобная сеть


FritzFrog полагается на способность делиться файлами по всей сети, как для заражения новых устройств, так и для запуска вредоносных элементов, например криптомайнера Monero.

Для обмена файлами между узлами FritzFrog использует скрытный безфайловый подход: файлы делятся на хранящиеся в памяти массивы двоичных данных, и вредоносный код отслеживает доступные массивы через хранение их в карте вместе со значением хэша каждого массива.

Когда узел А хочет получить файл от своего пира, узла B, он моет выслать узлу В запрос getblobstats чтобы узнать какими массивами он владеет. Затем узел А может получить конкретный массив через его хэш, как с помощью P2P команды getbin, так и с помощью HTTP по адресу http://1234/. Как только узел А получает все массивы, он собирает файл через модуль Assemble и запускает его.


Результат команды getblolbstats. Каждый узел в сети сообщает, каким он обладает массивом в соответствии с поддерживаемым списком файлов.

Присвоение


Отслеживание операций P2P ботнета задача трудная. В связи с распределенной природой сети, команды в ней можно передавать с любого узла на любой узел. Тем не менее, мы попробовали сравнить этот P2P ботнет с предыдущими аналогичными угрозами.

Даже при сравнении с другими P2P ботнетами FritzFrog остается уникальным: он не использует IRC как это делает IRCflu, в отличие от DDG он работает прямо в памяти, и он запускается на Unix-устройствах в противовес ботнету InterPlanetary Storm. Если он на кого и похож, особенно в плане наименования функций и нумерации версий, так это на Rakos, P2P ботнет на Golang, проанализированный ESET еще в 2016 году.

Отслеживание действий И смягчение последствий


Guardcore Labs предоставили скрипт по отслеживанию FritzFrog для запуска на SSH серверах. Он ищет следующие индикаторы ботнета:
  • Запуск процессов nginx, ifconfig или libexec, чей исполняемый файл более в системе не существует (как можно видеть ниже).
  • Прослушивание порта 1234.

В дополнение к этому, TCP трафик через порт 5555 может указывать на сетевой трафик к пулу Monero.

ubuntu@ip-111-11-11-11:~$ ./detect_fritzfrog.sh
FritzFrog Detection Script by Guardicore Labs
=============================================

[*] Fileless process nginx is running on the server.
[*] Listening on port 1234
[*] There is evidence of FritzFrog's malicious activity on this machine.

FritzFrog эксплуатирует особенность большинства систем сетевой защиты по принуждению трафика только через порт и протокол. Исключить подобные угрозы можно основанными на процессах правилами сегментации.

Слабые пароли оказываются ключевой уязвимостью для атак FritzFrog. Мы рекомендуем использовать сильные пароли и публичные ключи авторизации, что намного безопаснее. Кроме того, критически важно исключить публичный ключ FritzFrog из файла authorization_keys чтобы не дать злоумышленникам доступ к устройству. Роутеры и IoT устройства обычно раскрывают свой SSH и потому становятся уязвимы для атак FritzFrog; мы рекомендуем сменить таким устройствам SSH порт или, если функционал не используется, полностью отключить SSH.
Подробнее..

Инженер купил 220 нерабочих плат Raspberry Pi Model B и начал их ремонтировать

25.01.2021 12:19:59 | Автор: admin


Инженер и блогер Джеймс Доусон специализируется на обзорах одноплатных компьютеров, но сейчас он начал необычный марафон, а заодно решил подзаработать. Инженер купил на eBay партию примерно из 220 нерабочих компьютеров Raspberry Pi Model B за 61 фунт, то есть практически на вес.

Задача такая: диагностировать платы, найти неисправности, починить и продать. Платы простые, починить вроде бы легко.

Все купленные платы это Model B с объёмом оперативной памяти 256 или 512МБ в разном состоянии.

Диагностика


Первый этап провести диагностику одноплатников и определить неисправности каждого экземпляра. Как это сделать? Первым делом Джеймс разделил кучу на две части: которые грузятся и которые нет. Вторую группу он отложил на потом, а для первой взял TFT-дисплей Pi 3,5" и написал простой bash-скрипт для проверки USB-портов, Ethernet и видеовыхода.

Тут же проверялось, работают ли пины GPIO, поскольку дисплей подключался к ним (I2C, VCC и GND).


Тестирование периферии

По результатам диагностики образовалась такая картина:

Неисправность Количество Починено Не починено
Полностью рабочие 67 n/a n/a
Сломанный разъём SD-карты 30 0 30
Сломанный разъём USB 14 14 0
Лопнувший конденсатор фильтра 10 10 0
Не загружаются 80 0 80
Нет Ethernet 12 0 12
Нет сигнала HDMI 7 0 7

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

Кроме того, 67 плат в партии на самом деле оказались полностью работоспособны и не требовали ремонта.

Ремонт


Джеймс Доусон говорит, что не будет чинить платы с физическими повреждениями или без сигнала HDMI, хотя последние можно загрузить и использовать без монитора.

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

Многие платы оказались полностью работоспособны, просто там были погнуты контакты GPIO. Похоже, некоторые владельцы выкидывают свои малинки из-за этой неисправности.



Выпрямить их металлической линейкой минутное дело. В некоторых платах пришлось вставить недостающие пины.

Другая частая причина поломки неисправный разъём USB. Хотя неисправный это слабо сказано. Обычно они были выломаны с корнем.



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



Так мёртвые платы жертвуют органы живым, а вся партия Raspberry Pi сама поставляет комплектующие для своего ремонта. Здесь автор ничего не терял. Он говорит, что из 80 компьютеров, которые не загружаются, 60 не подлежали ремонту из-за физических повреждений платы.

USB-разъём просто припаивается на своё место:



Точно так же заменялись вылетевшие конденсаторы. Хотя плата нормально работает без них, Джеймс решил припаять их обратно.



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

К сожалению, разъёмы для SD-карт невозможно поставить одним модулем, как USB. Сейчас автор ждёт, когда ему придёт с AliExpress партия разъёмов SD, чтобы заменить 30 неисправных. На AliExpress они стоят копейки, если брать оптом.

Что касается плат с нерабочим Ethernet, то Джеймс планирует просто выпаять из них микросхему и сетевой разъём, что де-факто превращает Model B в Model A, которую он уже будет продавать дешевле.

Пока непонятно, что делать с платами, у которых не работает видеовыход HDMI. В принципе, они же нормально работают без монитора, а для многих применений монитор и не нужен. Например, если Raspberry Pi играет роль маршрутизатора или медиасервера. Возможно, они тоже поступят в продажу по сниженной цене.

Изначально автор планировал продавать рабочие платы по цене от 5 до 9 фунтов за штуку (5 фунтов за Model A, а максимальная цена 9 фунтов для Model B, которые вообще не потребовали ремонта). В реальности он выставил их на eBay парами по 15 фунтов без учёта доставки. В каждой паре одна отремонтированная плата и одна, которая не потребовала ремонта.

Благодаря тому, что пост из блога попал в топы на HN и Reddit, бизнес идёт успешно: за последние 24 часа продано 19 пар Raspberry Pi Model B, то есть 38 штук.



Несложно посчитать, какую прибыль получит инженер за 67 полностью рабочих и 24 отремонтированных компьютера плюс 12 экземпляров Model A, если продать их по цене от 5 до 7,5 фунтов.

Но давайте всё-таки посчитаем. Первоначальные инвестиции возвращаются в размере примерно 742,5фунта (91*7,5+12*5), и это всего за пару дней работы Нужно учесть, что когда придут SD-разъёмы из Китая, он может починить ещё 30 штук, а это еще 225 фунтов (минус стоимость SD-разъёмов), если считать отремонтированные Model B по 7,5 фунтов.

Итого 61 фунт превращается в 967,5 фунтов минус стоимость SD-разъёмов с AliExpress. Хотя конечно, продажи были бы скромнее без раскрутки проекта в блоге. Сейчас вся партия на eBay будет распродана за 2-3 дня, а без раскрутки есть вероятность, что их пришлось бы продавать 2-3 месяца.

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

P. S. И с точки зрения экологии переработка электроники и возвращение её к жизни плюс в карму автору.
Подробнее..

Перевод Как устроен блок питания, который работает в каждом системнике

24.05.2021 16:18:49 | Автор: admin

Блок питания извлечён из корпуса. Пучок проводов слева подключается к компьютеру. Большой компонент посередине типа трансформатора это фильтрующий индуктор. Кликабельно, как и все фотографии в статье

Вы когда-нибудь задумывались, что находится внутри блока питания (БП) вашего компьютера? Задача БП преобразовать питание из сети (120 или 240 В переменного тока, AC) в стабильное питание постоянного, то есть однонаправленного тока (DC), который нужен вашему компьютеру. БП должен быть компактным и дешёвым, при этом эффективно и безопасно преобразовывать ток. Для этих целей при изготовлении используются различные методы, а сами БП внутри устроены гораздо сложнее, чем вы думаете.

В этой статье мы разберём блок стандарта ATX и объясним, как он работает1.

Как и в большинстве современных БП, в нашем используется конструкция, известная как импульсный блок питания (ИБП). Это сейчас они очень дёшевы, но так было не всегда. В 1950-е годы сложные и дорогие ИБП использовались разве что в ракетах и космических спутниках с критическими требованиями к размеру и весу. Однако к началу 1970-х новые высоковольтные транзисторы и другие технологические усовершенствования значительно удешевили ИБП, так что их стали широко использовать в компьютерах. Сегодня вы можете за несколько долларов купить зарядное устройство для телефона с ИБП внутри.

Наш ИБП формата ATX упакован в металлический корпус размером с кирпич, из которого выходит множество разноцветных кабелей. Внутри корпуса мы видим плотно упакованные компоненты. Инженеры-конструкторы явно были озабочены проблемой компактности устройства. Многие компоненты накрыты радиаторами. Они охлаждают силовые полупроводники. То же самое для всего БП делает встроенный вентилятор. На КДПВ он справа.

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

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

Входная фильтрация шума


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

Фильтр ниже состоит из индукторов (тороидальных катушек) и конденсаторов. Квадратные серые конденсаторы специальные компоненты класса X для безопасного подключения к линиям переменного тока.


Компоненты входного фильтра

Преобразование AC/DC


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


На мостовом выпрямителе видна маркировка GBU606. Цепь фильтра находится слева от выпрямителя. Большой чёрный конденсатор справа один из удвоителей напряжения. Маленький жёлтый конденсатор это специальный керамический Y-конденсатор, который защищает от всплесков напряжения

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


На двух схемах показан поток тока при колебаниях входного сигнала AC. Четыре диода заставляют ток течь в направлении по стрелке

Современные БП принимают универсальное входное напряжение от 85 до 264 вольт переменного тока, поэтому могут использоваться в разных странах независимо от напряжения в местной сети. Однако схема этого старого БП не могла справиться с таким широким диапазоном. Поэтому предусмотрен переключатель для выбора 115 или 230 В.


Переключатель 115/230 В

Переключатель использует умную схему с удвоителем напряжения. Идея в том, что при закрытом переключателе (на 115 В) вход AC обходит два нижних диода в мостовом выпрямителе, а вместо этого подключается непосредственно к двум конденсаторам. Когда плюс на верхнем входе AC, полное напряжение получает верхний конденсатор. А когда плюс снизу, то нижний. Поскольку выход DC идёт с обоих конденсаторов, на выходе всегда получается двойное напряжение. Дело в том, что остальная часть БП получает одинаковое напряжение независимо от того, на входе 115 или 230 В, что упрощает его конструкцию. Недостаток удвоителя в том, что пользователь обязан установить переключатель в правильное положение, иначе рискует повредить БП, а для самого БП требуются два больших конденсатора. Поэтому в современных БП удвоитель напряжения вышел из моды.


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

Две стороны БП


В целях безопасности высоковольтные и низковольтные компоненты разделены механически и электрически, см. фотографию ниже. На основной стороне находятся все цепи, которые подключаются к сети AC. На вторичной стороне низковольтные цепи. Две стороны разделены пограничной изоляцией, которая отмечена зелёным пунктиром на фотографии. Через границу не проходит никаких электрических соединений. Трансформаторы пропускают энергию через эту границу через магнитные поля без прямого электрического соединения. Сигналы обратной связи передаются на основную сторону с помощью оптоизоляторов, то есть световыми импульсами. Это разделение является ключевым фактором в безопасной конструкции: прямое электрическое соединение между линией AC и выходом БП создаёт опасность удара электрическим током.


Источник питания с маркировкой основных элементов. Радиаторы, конденсаторы, плата управления и выходные кабели удалены ради лучшего обзора (SB означает источник резервного питания, standby supply)

Импульсы к трансформатору


К этому моменту входной переменный ток преобразован в высоковольтный постоянный ток около 320 В2. Постоянный ток нарезается на импульсы переключающим (импульсным) транзистором (switching transistor на схеме выше). Это силовой МОП-транзистор (MOSFET)3. Поскольку во время использования он нагревается, то установлен на большом радиаторе. Импульсы подаются в главный трансформатор, который в некотором смысле является сердцем БП.

Трансформатор состоит из нескольких катушек проволоки, намотанных на намагничиваемый сердечник. Высоковольтные импульсы, поступающие в первичную обмотку трансформатора, создают магнитное поле. Сердечник направляет это магнитное поле на другие, вторичные обмотки, создавая в них напряжение. Так ИБП безопасно вырабатывает выходной ток: между двумя сторонами трансформатора нет электрического соединения, только соединение через магнитное поле. Другим важным аспектом является то, что в первичной обмотке много оборотов проволоки вокруг сердечника, а на вторичных контурах гораздо меньше. В результате получается понижающий трансформатор: выходное напряжение намного меньше входного, но при гораздо большем вольтаже.

Переключающий транзистор3 управляется интегральной схемой под названием ШИМ-контроллер режима тока UC3842B. Этот чип можно считать мозгом БП. Он генерирует импульсы на высокой частоте 250 килогерц. Ширина каждого импульса регулируется для обеспечения необходимого выходного напряжения: если напряжение начинает падать, чип производит более широкие импульсы, чтобы пропускать больше энергии через трансформатор4.

Вторичная сторона


Теперь можно посмотреть на вторую, низковольтную часть БП. Вторичная схема производит четыре выходных напряжения: 5, 12, ?12 и 3,3 вольта. Для каждого выходного напряжения отдельная обмотка трансформатора и отдельная схема для получения этого тока. Силовые диоды (ниже) преобразуют выходы трансформатора в постоянный ток. Затем индукторы и конденсаторы фильтруют выход от всплесков напряжения. БП должен регулировать выходное напряжение, чтобы поддерживать его на должном уровне даже при увеличении или уменьшении нагрузки. Интересно, что в БП используется несколько различных методов регулирования.


Крупным планом показаны выходные диоды. Слева вертикально установлены цилиндрические диоды. В центре пары прямоугольных силовых диодов Шоттки, в каждом корпусе по два диода. Эти диоды прикреплены к радиатору для охлаждения. Справа обратите внимание на два медных провода в форме скоб. Они используются в качестве резисторов для измерения тока

Основными являются выходы 5 и 12 В. Они регулируются одной микросхемой контроллера на основной стороне. Если напряжение слишком низкое, микросхема увеличивает ширину импульсов, пропуская больше мощности через трансформатор и увеличивая напряжение на вторичной стороне БП. А если напряжение слишком высокое, чип уменьшает ширину импульса. Примечание: одна и та же схема обратной связи управляет выходами на 5 и 12 В, поэтому нагрузка на одном выходе может изменять напряжение на другом. В более качественных БП два выхода регулируются по отдельности5.


Нижняя сторона печатной платы. Обратите внимание на большое расстояние между цепями основной и вторичной сторон БП. Также обратите внимание, какие широкие металлические дорожки на основной стороне БП для тока высокого напряжения и какие тонкие дорожки для схем управления

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

Источник питания также обеспечивает отрицательное выходное напряжение (?12 В). Это напряжение в основном устарело, но использовалось для питания последовательных портов и слотов PCI. Регулирование питания ?12 В кардинально отличается от регулирования +5 и +12В. Выход ?12 В управляется стабилитроном (диодом Зенера) это специальный тип диода, который блокирует обратный ток до определённого уровня напряжения, а затем начинает проводить его. Избыточное напряжение рассеивается в виде тепла через силовой резистор (розовый) под управлением транзистора и стабилитрона (поскольку этот подход расходует энергию впустую, современные высокоэффективные БП не используют такой метод регулирования).


Питание ?12 В регулируется крошечным стабилитроном ZD6 длиной около 3,6 мм на нижней стороне печатной платы. Соответствующий силовой резистор и транзистор A1015 находятся на верхней стороне платы

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


Магнитный усилитель представляет собой кольцо из ферритового материала с особыми магнитными свойствами. Вокруг кольца намотано несколько витков проволоки

Управляющая плата


В блоке питания есть небольшая плата, на которой размещена схема управления. Эта плата сравнивает напряжение с эталонным, чтобы генерировать сигналы обратной связи. Она отслеживает вольтаж также для того, чтобы генерировать сигнал питание в норме (power good). Схема установлена на отдельной перпендикулярной плате, поэтому не занимает много места в БП.


Основные компоненты установлены на верхней стороне платы со сквозными отверстиями, а нижняя сторона покрыта крошечными SMD-компонентами, которые нанесены путём поверхностного монтажа. Обратите внимание на резисторы с нулевым сопротивлением в качестве перемычек

Источник резервного питания


В БП есть ещё вторая цепь для резервного питания9. Даже когда компьютер формально выключен, пятивольтовый источник резервного питания обеспечивает ему мощность 10 Вт для функций, которые продолжают работать: часы реального времени, функция пробуждения по локальной сети и др. Цепь резервного питания является почти независимым БП: она использует отдельную управляющую микросхему, отдельный трансформатор и отдельные компоненты на вторичной стороне DC, но те же самые компоненты на основной стороне AC. Эта система гораздо меньшей мощности, поэтому в цепи трансформатор меньшего размера.


Чёрно-жёлтые трансформаторы: трансформатор для резервного питания находится слева, а основной трансформатор справа. Перед ним установлена микросхема для управления резервным питанием. Большой цилиндрический конденсатор справа компонент удвоителя напряжения. Белые капли это силикон, который изолирует компоненты и удерживает их на месте

Вывод


Блок питания ATX сложно устроен внутри, с множеством компонентов, от массивных индукторов и конденсаторов до крошечных компонентов поверхностного монтажа10. Однако эта сложность позволяет выпускать эффективные, маленькие и безопасные БП. Для сравнения, я когда-то писал о блоке питания 1940-х годов, который выдавал всего 85 ватт мощности, но был размером с чемодан, весил 50 кг и стоил сумасшедшие деньги. В наше время с продвинутыми полупроводниками делают гораздо более мощные БП дешевле 50 долларов, и такое устройство поместится у вас в руке.




Блок питания REC-30 для телетайпа Model 19 (ВМФ США) 1940-х годов

Я уже писал о БП, включая историю блоков питания в IEEE Spectrum. Вам также могут понравиться детальные разборы зарядного устройства Macbook и зарядного устройства iPhone.

Примечания и ссылки


1 Intel представила стандарт ATX для персональных компьютеров в 1995 году. Стандарт ATX (с некоторыми обновлениями) по-прежнему определяет конфигурацию материнской платы, корпуса и блока питания большинства настольных компьютеров. Здесь мы изучаем блок питания 2005 года, а современные БП более продвинутые и эффективные. Основные принципы те же, но есть некоторые изменения. Например, вместо магнитных усилителей почти везде используют преобразователи DC/DC.


Этикетка на блоке питания

На этикетке БП указано, что он изготовлен компанией Bestec для настольного компьютера Hewlett-Packard Dx5150. Этот БП слегка не соответствует формату ATX, он более вытянут в длину. [вернуться]

2 Вы можете задать вопрос, почему AC напряжением 230 В преобразуется в постоянный ток 320 В. Причина в том, что напряжение переменного тока обычно измеряется как среднеквадратичное, которое в каком-то смысле усредняет изменяющуюся форму волны. По факту в 230-вольтовом сигнале AC есть пики до 320 вольт. Конденсаторы БП заряжаются через диоды до пикового напряжения, поэтому постоянный ток составляет примерно 320 вольт (хотя немного провисает в течение цикла). [вернуться]

3 Силовой транзистор представляет собой силовой МОП-транзистор FQA9N90C. Он выдерживает 9 ампер и 900 вольт. [вернуться]

4 Интегральная схема питается от отдельной обмотки на трансформаторе, которая выдаёт 34 вольта для её работы. Налицо проблема курицы и яйца: управляющая микросхема создаёт импульсы для трансформатора, но трансформатор питает управляющую микросхему. Решение специальная цепь запуска с резистором 100 k между микросхемой и высоковольтным током. Она обеспечивает небольшой ток для запуска микросхемы. Как только чип начинает отправлять импульсы на трансформатор, то питается уже от него. [вернуться]

5 Метод использования одного контура регулирования для двух выходов называется перекрёстным регулированием. Если нагрузка на одном выходе намного выше другого, напряжения могут отклоняться от своих значений. Поэтому во многих БП есть минимальные требования к нагрузке на каждом выходе. Более продвинутые БП используют DC/DC преобразователи для всех выходов, чтобы контролировать точность напряжения. Дополнительные сведения о перекрёстном регулировании см. в этих двух презентациях. Один из обсуждаемых методов многоуровневая укладка выходных обмоток, как в нашем БП. В частности, 12-вольтовый выход реализован в виде 7-вольтового выхода поверх 5-вольтового выхода, что даёт 12 вольт. При такой конфигурации ошибка 10% (например) в 12-вольтовой цепи будет составлять всего 0,7 В, а не 1,2 В. [вернуться]

6 Оптоизоляторы представляют собой компоненты PC817, которые обеспечивают 5000 вольт изоляции между сторонами БП (то есть между высокой и низкой сторонами). Обратите внимание на прорезь в печатной плате под оптоизоляторами. Это дополнительная мера безопасности: она гарантирует, что ток высокого напряжения не пройдёт между двумя сторонами оптоизолятора вдоль поверхности печатной платы, например, при наличии загрязнения или конденсата (в частности, прорезь увеличивает расстояние утечки). [вернуться]

7 Ширина импульса через магнитный усилитель устанавливается простой схемой управления. В обратной части каждого импульса индуктор частично размагничивается. Схема управления регулирует напряжение размагничивания. Более высокий вольтаж усиливает размагничивание. Тогда индуктору требуется больше времени для повторного намагничивания, и, таким образом, он дольше блокирует входной импульс. При более коротком импульсе в цепи выходное напряжение уменьшается. И наоборот, более низкое напряжение размагничивания приводит к меньшему размагничиванию, поэтому входной импульс блокируется не так долго. В итоге выходное напряжение регулируется изменением напряжения размагничивания. Обратите внимание, что ширина импульса в магнитном усилителе регулируется управляющей микросхемой. Магнитный усилитель сокращает эти импульсы по мере необходимости при регулировании выходного напряжения 3,3 В. [вернуться]

8 Плата управления содержит несколько микросхем, включая операционный усилитель LM358NA, чип супервизора/сброса TPS3510P, четырёхканальный дифференциальный компаратор LM339N и прецизионный эталон AZ431. Чип супервизора интересный он специально разработан для БП и контролирует выходное напряжение, чтобы оно было не слишком высоким и не слишком низким. Прецизионный эталон AZ431 это вариант эталонного чипа TL431, который часто используется в БП для обеспечения опорного (контрольного) напряжения. Я уже писал о TL431. [вернуться]

9 Источник резервного питания использует другую конфигурацию обратноходовой трансформатор. Здесь установлена управляющая микросхема A6151 с переключающим транзистором, что упрощает конструкцию.


Схема БП с использованием A6151. Она взята из справочника, поэтому не идентична схеме нашего БП, хотя близка к ней
[вернуться]

10 Если хотите изучить подробные схемы различных БП формата ATX, рекомендую сайт Дэна Мельника. Удивительно, сколько существует реализаций БП: различные топологии (полумостовые или прямые), наличие или отсутствие преобразования коэффициента мощности (PFC), разнообразные системы управления, регулирования и мониторинга. Наш БП довольно похож на БП с прямой топологией без PFC, внизу той странички на сайте Дэна. [вернуться]
Подробнее..

Перевод Как x86_x64 адресует память

22.06.2020 16:10:43 | Автор: admin
Сегодня я собираюсь поговорить про адресацию памяти: один, казалось бы, небольшой, и тем не менее удивительно непростой элемент семантики команд архитектуры х86_64. В особенности хочется поговорить про команду mov и то, как через только одну эту команду х86_64 пользователю становятся доступны различные методы адресации памяти.

Я не буду говорить про остальные затрагивающие память команды (то есть, благодаря CISC, почти все остальные), команды которые пишут массивные фрагменты памяти (это о тебе, fxsave), или иные касающиеся темы вопросы (модели кода, независящий от адреса код, и бинарная релокация). Я также не буду затрагивать исторические режимы адресации или режимы, которые активны при работе процессора x86_64 не в 64-битном режиме (т.е. любые отличные от long mode с 64-битным кодом).

Некоторые ограничения


Несмотря на кошмарное наследие кодирования команд х86_64, а может и благодаря ему, у адресации памяти есть некоторые ограничения.

Начнем с хорошего:

  • На достаточно высоком уровне в архитектуре х86_64 есть всего два режима адресации.
  • Все регистры в обоих режимах адресации должны быть строго одинакового размера. Другими словами, мы не можем странным образом смешивать 64, 32 и 16-битные регистры и получать актуальный адрес в кодировании х86_64 для подобного маневра попросту нет места.

В остальном все не столь радужно:

  • Один из этих двух режимов адресации все еще абсурдно сложен.
  • Регистры должны быть одинакового размера, но не обязаны быть той же разрядности что и режим процессора. Например, если мы добавим в нашем кодировании префикс байт (0x67), мы можем пользоваться 32-битными регистрами вместо 64-битных.

Адресация Scale-Index-Base-Displacement


Я не имею представления как назвать этот режим, поэтому называю его Scale-Index-Base-Displacement. Насколько я понимаю, ни Intel, ни AMD вообще не воспринимают его как единый режим и вместо этого упоминают в виде типичного набора связных режимов с широким диапазоном различных методов кодирования.

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

  • Scale: 2-битный коэффициент константы, обычно равный 1, 2, 4 или 8.
  • Index: Любой регистр общего назначения (rax, rbx, &c).
  • Base: Любой регистр общего назначения.
  • Displacement: Интегральный сдвиг. Обычно даже в 64-битном режиме он ограничен 32 битами, но с использованием некоторых методов кодирования может быть и 64-битным. Мы об этом еще поговорим.

Эти четыре параметра можно объединить в несколько различных комбинаций, полный список в порядке увеличения сложности можно увидеть ниже:

  • Displacement
  • Base
  • Base + Index
  • Base + Displacement
  • Base + Index + Displacement
  • Base + (Index * Scale)
  • (Index * Scale) + Displacement
  • Base + (Index * Scale) + Displacement

Давайте разберем каждую комбинацию по порядку.

Displacement


Это, пожалуй, самый простой механизм адресации в семье х86: displacement обрабатывается как абсолютный адрес памяти, и сам по себе, к несчастью, совершенно бесполезен в архитектуре х86_64. Помните, мы говорили, что displacement почти всегда ограничен 32 битами? Так как абсолютный адрес в х86_64 это 64 бита (на самом деле 48, но это неважно), он попросту не поместится в displacement, однако в виде исключения можно использовать 64-битный displacement с регистром a*.

Синтаксис Intel:

; store the qword at 0x00000000000000ff into raxmov rax, [0xff]; store the dword at 0x00000000000000ff into eaxmov eax, [0xff]; store the word at 0x00000000000000ff into axmov ax, [0xff]; store the byte at 0x00000000000000ff into almov al, [0xff]

gas (GNU ассемблер) и в 32, и в 64-битном режимах ссылается на них как на movabs.

Зачем мне (или моему компилятору) пользоваться этим режимом?


Для начала, из-за моделей кода, не имеющих отношения к данному посту. Подробнее по теме можно прочесть в замечательном посте Eli Bendersky по ссылке.

А теперь по делу: у большинства программ есть как минимум несколько статичных адресов, которые определяются в compile-time, аналогично глобальным переменным. Например, результатом следующей тривиальной программы:

extern long var;void f(long x) { var = x; }

будет:

f:        mov     rax, rdi        movabs  QWORD PTR [var], rax        ret

(Посмотреть на Godbolt.)

Base


Адресация через регистр base добавляет еще один уровень неопределенности поверх абсолютной адресации: вместо использования закодированного в поле displacement команды абсолютного адреса, адрес загружается из указанного регистра общего пользования (Причем любого такого регистра! Ура!)

Эта неопределенность позволяет нам проводить абсолютную адресацию с произвольным регистром назначения по следующему шаблону:

; store the immediate (not displacement) into rbxmov rbx, 0xacabacabacabacab; store the qword at the address stored in rbx into rcxmov rcx, [rbx]

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

Зачем мне (или моему компилятору) пользоваться этим режимом?


Затем что порой после очередной операции мы уже посчитали адрес и хотим им воспользоваться.

Разобрав вариант в displacement, мы можем найти хороший пример такого приема:

mov rax, qword ptr [rax]

Base + Index


Эта комбинация аналогична регистру base за тем исключением, что мы добавляем значение регистра index. Пример:

; store the qword in rcx into the memory address computed; as the sum of the values in rax and rbxmov [rax + rbx], rcx

Зачем мне (или моему компилятору) пользоваться этим режимом?


Найти подходящий пример для такого режима оказалось для меня непростой задачей, поэтому мои коллеги, конечно же, сразу же подобрали один:

int foo(char * buf, int index) {  return buf[index];}

Результат:

push    rbpmov     rbp, rspmov     qword ptr [rbp - 8], rdimov     dword ptr [rbp - 12], esimov     rax, qword ptr [rbp - 8]  ; rax is bufmovsxd  rcx, dword ptr [rbp - 12] ; rcx is indexmovsx   eax, byte ptr [rax + rcx] ; store buf[index] into eaxpop     rbpret

(Посмотреть на Godbolt.)

Оглядываясь назад, мы можем заметить очевидное: в случаях, когда ни стартовый адрес массива, ни сдвиг в массив не зафиксированы в compile-time, Base + Index идеально подходит для моделирования доступов к массиву.

Base + Displacement


Больше неопределенности! Если вы еще не догадались, подсчет актуального адреса и регистром base, и полем displacement соответствует двум следующим операциям:

  1. Мы загружаем значение из регистра base
  2. Мы добавляем загруженное значение к значению поля displacement

Затем мы берем полученную сумму за фактический адрес. Пример:

; add 0xcafe to the value stored in rax; then, store the qword at the computed address into rbxmov rbx, [rax + 0xcafe]

Зачем мне (или моему компилятору) пользоваться этим режимом?


Некоторые режимы адресации, как мы уже видели на примере Base + Index, естественным образом отображают семантику С-подобных массивов. Base + Displacement можно рассматривать в таком же ключе, но со стороны структурной семантики: регистр base содержит адрес к началу структуры, а поле displacement содержит фиксированный сдвиг в эту структуру. Пример:

struct foo {    long a;    long b;};long bar(struct foo *foobar) {    return foobar->b;}

Результат:

push    rbpmov     rbp, rspmov     qword ptr [rbp - 8], rdimov     rax, qword ptr [rbp - 8] ; rax is foobarmov     rax, qword ptr [rax + 8] ; rax + 8 is foobar->b; store back into raxpop     rbpret

(Посмотреть на Godbolt.)

Если задуматься о конструкции и планировке стека в начале каждой функции как о самостоятельной структуре, пример выше становится очевиден: доступы вида [rbp - N] это по сути stack->objN.

Base + Index + Displacement


Если вы разобрались в предыдущем режиме, логичным следующим шагом будет добавить к нему значение регистра index, создавая новый, почти аналогичный семантически режим.

Как в примере выше, но с еще одним регистром, результат будет выглядеть следующим образом:

; add 0xcafe to the values stores in rax and rcx; then, store the qword at the computer address into rbxmov rbx, [rax + rcx + 0xcafe]

Зачем мне (или моему компилятору) пользоваться этим режимом?


Base + Index + Displacement естественным образом моделирует доступ к структуре внутри массива, точно так же как Base + Displacement естественным образом моделирует доступ к структуре, а Base + Index естественным образом моделирует доступ к массиву.

Не без труда, но с помощью -O1 мне удалось заставить clang скомпилировать пример в Godbolt:

struct foo {    long a;    long b;};long square(struct foo foos[], long i) {    struct foo x = foos[i];    return x.b;}

Краткий результат:

shl     rsi, 4mov     rax, qword ptr [rdi + rsi + 8] ; rdi is foos, rsi is i, 8 is the field offsetret

(Посмотреть на Godbolt.)

Base + (Index * Scale)


Наше первое умножение!

Поле scale похоже на поле displacement тем, что они оба являются закодированным в нашу команду коэффициентом константы, однако scale, в отличие от displacement, сильно ограничен: так как его диапазон составляет всего два бита, значения у scale может быть всего четыре: 1, 2, 4 или 8.

Как можно догадаться из названия, поле scale используется для скалирования, т.е. умножения, другого поля на себя. Если говорить точнее, оно всегда скалирует регистр index, и не может без него использоваться.

Зачем мне (или моему компилятору) пользоваться этим режимом?


В отличие от массива структур из предыдущих примеров, Base + (Index * Scale), кроме всего прочего, естественным образом моделирует доступ к массиву указателей. Пример:

struct foo {    long a;    long b;};long bar(struct foo *foos[], long i) {    struct foo *x = foos[i];    return x->b;}

Результат:

mov     rax, qword ptr [rdi + 8*rsi] ; rdi is foos, rsi is i, 8 is the scale (pointer-sized!)mov     rax, qword ptr [rax + 8]ret

(Посмотреть на Godbolt.)

(Index * Scale) + Displacement


Почти как на примере выше, эта комбинация без лишних сложностей меняет регистр base на поле displacement.

Зачем мне (или моему компилятору) пользоваться этим режимом?


(Index * Scale) + Displacement естественным образом моделирует особый случай доступа к массиву: когда массив можно статически (т.е. глобально) адресовать, а размер элементов можно вычислить через scale. Пример:

int tbl[10];int foo(int i) {    return tbl[i];}

Результат:

movsxd  rax, edimov     eax, dword ptr [4*rax + tbl] ; rax is i, 4 is the scale (sizeof(int) == 4)ret

(Посмотреть на Godbolt.)

Base + (Index * Scale) + Displacement


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

Зачем мне (или моему компилятору) пользоваться этим режимом?


Base + (Index * Scale) + Displacement естественным образом моделирует доступ к двумерному массиву. Пример:

long tbl[10][10];long foo(long i, long j) {    return tbl[i][j];}

Результат:

lea     rax, [rdi + 4*rdi]shl     rax, 4mov     rax, qword ptr [rax + 8*rsi + tbl]ret

(Посмотреть на Godbolt.)

RIP-относительная адресация


Выше мы описали режим адресации, который почти идентичен своему историческому эквиваленту в х86_32, и отличается в первую очередь использованием 64-битных регистров GPR, и порой 64-битными смещениями. Однако главным отличием является добавление абсолютно нового режима адресации под названием RIP-относительная (RIP-relative) адресация.

Почему этот режим называется RIP-относительным? Потому что он кодирует смещение относительно значения регистра RIP (в особенности RIP не текущей, а следующей команды). Обычно это выражается уже знакомым нам синтаксисом [Base + Displacement], вот только вместо GPR регистром base теперь является rip. Пример:

mov rax, [rip + 16]

Зачем мне (или моему компилятору) пользоваться этим режимом?


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

Пример компиляции с использованием -O1 и -fpic:

long tbl[10];int foo(int i) {    return tbl[i];}

Для него в архитектуре х86_64 нам потребуются всего два mov:

foo:        mov     rax, qword ptr [rip + tbl@GOTPCREL]        mov     rax, qword ptr [rax + 8*rdi]        ret

Однако в архитектуре х86_32 нам их потребуется три, плюс шаблоны:

foo:        call    .L0$pb.L0$pb:        pop     eax.Ltmp0:        add     eax, offset _GLOBAL_OFFSET_TABLE_+(.Ltmp0-.L0$pb)        mov     ecx, dword ptr [esp + 4]        mov     eax, dword ptr [eax + tbl@GOT]        mov     eax, dword ptr [eax + 4*ecx]        ret

Напоследок: сегментация


Архитектура х86_64 убрала всю сегментацию, но только почти. Благодаря плоскому адресному пространству регистры сегментов более не требуются, но местами все еще проявляются:

  • Linux (точнее glibc) использует fs в пользовательском пространстве для доступа к настраиваемым ядром сегментам TLS. Спецификацию этих сегментов можно обнаружить в per-CPU конфигурации GDT (ссылка). Если предположить что ничего в glibc (или любой вашей libc) не использует gs, вы можете свободно им пользоваться.
  • В пространстве ядра Linux использует gs для хранения основного адреса региона per-CPU переменной. Мы можем наблюдать это в определении макроса PER_CPU_VAR (ссылка):
    #define PER_CPU_VAR(var)  %__percpu_seg:var
    
  • В х86_64 определение растет:
    %gs:var
    

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

Кстати, вот пример локально-поточной переменной:

int __thread x = 0;int foo(void) {    int *y = &x;    return *y;}

Результат:

push    rbpmov     rbp, rspmov     rax, qword ptr fs:[0]    ; grab the base address of the thread-local storage arealea     rax, [rax + x@TPOFF]     ; calculate the effective address of x within the TLSmov     qword ptr [rbp - 8], rax ; store the address of x into ymov     rax, qword ptr [rbp - 8]mov     eax, dword ptr [rax]pop     rbpret

(Прочесть на Godbolt.)
Подробнее..

Перевод Разбираемся в моделях кода архитектуры x64

01.07.2020 18:14:54 | Автор: admin
Какой моделью кода мне воспользоваться? часто возникающий, но нечасто разбираемый вопрос при написании кода для архитектуры х64. Тем не менее, это довольно интересная проблема, и для понимания генерируемого компиляторами машинного кода х64 полезно иметь представление о моделях кода. Кроме того, для тех, кто беспокоится о производительности вплоть до мельчайших команд, выбор модели кода влияет и на оптимизацию.

Информация по этой теме в сети, или где бы то ни было еще, встречается редко. Самым важным из доступных ресурсов является официальный х64 ABI, скачать его можно по ссылке (далее по тексту он будет упоминаться как ABI). Часть информации также можно найти на man-страницах gcc. Задача данной статьи предоставить доступные рекомендации по теме, обсудить связанные с ней вопросы, а так же хорошими примерами через используемый в работе код продемонстрировать некоторые концепты.

Важное замечание: эта статья не является обучающим материалом для начинающих. Перед ознакомлением рекомендуется уверенное владение C и ассемблером, а так же базовое знакомство с архитектурой х64.



Также смотрите нашу предыдущую публикацию на схожую тему: Как x86_x64 адресует память



Модели кода. Мотивационная часть


В архитектуре х64 отсылки и на код, и на данные ведутся через командно-относительные (или, используя жаргон х64, RIP-относительные) модели адресации. В этих командах сдвиг от RIP ограничен 32 битами, однако могут возникнуть случаи, когда команде при попытке адресовать часть памяти или данных попросту не хватит сдвига в 32 бит, например при работе с программами больше двух гигабайт.

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

Таким образом, компромиссом становятся модели кода. [1] Модель кода это формальное соглашение между программистом и компилятором, в котором программист указывает свои намерения относительно размера ожидаемой программы (или программ), в которую попадет компилируемый в данный момент объектный модуль. [2] Модели кода нужны для того чтобы программист мог сказать компилятору: не волнуйся, этот объектный модуль пойдет только в небольшие программы, так что можно пользоваться быстрыми RIP-относительными режимами адресации. С другой стороны, он может сказать компилятору следующее: мы собираемся компоновать этот модуль в большие программы, так что пожалуйста используй неторопливые и безопасные абсолютные режимы адресации с полным 64-битным сдвигом.

О чем расскажет эта статья


Мы поговорим о двух описанных выше сценариях, малой модели кода и большой модели кода: первая модель говорит компилятору, что 32-битного относительного сдвига должно хватить для всех ссылок на код и данные в объектном модуле; вторая настаивает на использовании компилятором абсолютных 64-битных режимов адресации. Кроме того, существует еще и промежуточный вариант, так называемая средняя модель кода.

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

Исходный пример на С


Для демонстрации обсуждаемых в этой статье концептов я воспользуюсь представленной ниже программой на С и скомпилирую ее с различными моделями кода. Как можно видеть, функция main получает доступ к четырем разным глобальным массивам и одной глобальной функции. Массивы отличаются двумя параметрами: размером и видимостью. Размер важен для объяснения средней модели кода и не понадобится в работе с малой и большой моделями. Видимость важна для работы PIC-моделей кода и бывает либо статичной (видимость только в исходном файле), либо глобальной (видимость всем скомпонованным в программу объектам).

int global_arr[100] = {2, 3};static int static_arr[100] = {9, 7};int global_arr_big[50000] = {5, 6};static int static_arr_big[50000] = {10, 20};int global_func(int param){    return param * 10;}int main(int argc, const char* argv[]){    int t = global_func(argc);    t += global_arr[7];    t += static_arr[7];    t += global_arr_big[7];    t += static_arr_big[7];    return t;}

gcc использует модель кода как значение опции -mcmodel. Кроме того, флагом -fpic можно задать PIC компиляцию.

Пример компиляции в объектный модуль через большую модель кода с использованием PIC:

> gcc -g -O0 -c codemodel1.c -fpic -mcmodel=large -o codemodel1_large_pic.o

Малая модель кода


Перевод цитаты из man gcc на тему малой модели кода:

-mcmodel=small
Генерация кода для малой модели: программа и ее символы должны быть скомпонованы в нижних двух гигабайтах адресного пространства. Размер указателей 64 бит. Программы могут быть скомпонованы и статически, и динамически. Это основная модель кода.


Другими словами, компилятор может спокойно считать, что код и данные доступны через 32-битный RIP-относительный сдвиг из любой команды в коде. Давайте взглянем на дизассемблированный пример программы на С, которую мы скомпилировали через не-PIC малую модель кода:

> objdump -dS codemodel1_small.o[...]int main(int argc, const char* argv[]){  15: 55                      push   %rbp  16: 48 89 e5                mov    %rsp,%rbp  19: 48 83 ec 20             sub    $0x20,%rsp  1d: 89 7d ec                mov    %edi,-0x14(%rbp)  20: 48 89 75 e0             mov    %rsi,-0x20(%rbp)    int t = global_func(argc);  24: 8b 45 ec                mov    -0x14(%rbp),%eax  27: 89 c7                   mov    %eax,%edi  29: b8 00 00 00 00          mov    $0x0,%eax  2e: e8 00 00 00 00          callq  33 <main+0x1e>  33: 89 45 fc                mov    %eax,-0x4(%rbp)    t += global_arr[7];  36: 8b 05 00 00 00 00       mov    0x0(%rip),%eax  3c: 01 45 fc                add    %eax,-0x4(%rbp)    t += static_arr[7];  3f: 8b 05 00 00 00 00       mov    0x0(%rip),%eax  45: 01 45 fc                add    %eax,-0x4(%rbp)    t += global_arr_big[7];  48: 8b 05 00 00 00 00       mov    0x0(%rip),%eax  4e: 01 45 fc                add    %eax,-0x4(%rbp)    t += static_arr_big[7];  51: 8b 05 00 00 00 00       mov    0x0(%rip),%eax  57: 01 45 fc                add    %eax,-0x4(%rbp)    return t;  5a: 8b 45 fc                mov    -0x4(%rbp),%eax}  5d: c9                      leaveq  5e: c3                      retq

Как можно видеть, доступ ко всем массивам организован одинаково с использованием RIP-относительного сдвига. Однако в коде сдвиг равен 0, поскольку компилятор не знает, где будет размещен сегмент данных, поэтому для каждого такого доступа он создает релокацию:

> readelf -r codemodel1_small.oRelocation section '.rela.text' at offset 0x62bd8 contains 5 entries:  Offset          Info           Type           Sym. Value    Sym. Name + Addend00000000002f  001500000002 R_X86_64_PC32     0000000000000000 global_func - 4000000000038  001100000002 R_X86_64_PC32     0000000000000000 global_arr + 18000000000041  000300000002 R_X86_64_PC32     0000000000000000 .data + 1b800000000004a  001200000002 R_X86_64_PC32     0000000000000340 global_arr_big + 18000000000053  000300000002 R_X86_64_PC32     0000000000000000 .data + 31098

Давайте в качестве примера полностью декодируем доступ к global_arr. Интересующий нас дизассемблированный сегмент:

  t += global_arr[7];36:       8b 05 00 00 00 00       mov    0x0(%rip),%eax3c:       01 45 fc                add    %eax,-0x4(%rbp)

RIP-относительная адресация относительна очередной команде, таким образом сдвиг необходимо запатчить в команду mov таким образом, чтобы он соответствовал 0х3с. Нас интересует вторая релокация, R_X86_64_PC32, она указывает на операнд mov по адресу 0x38 и означает следующее: берем значение символа, добавляем слагаемое и вычитаем указываемый релокацией сдвиг. Если вы все корректно посчитали, вы увидите как результат разместит относительный сдвиг между очередной командой и global_arr, плюс 0х1с. Поскольку 0х1с означает седьмой int в массиве (в архитектуре х64 размер каждого int составляет 4 байта), то этот относительный сдвиг нам и нужен. Таким образом, используя RIP-относительную адресацию, команда корректно ссылается на global_arr[7].

Также интересно отметить следующее: пусть команды доступа к static_arr здесь и схожи, его переадресация использует другой символ, тем самым вместо конкретного символа указывая в секцию .data. Виной тому действия компоновщика, он размещает статический массив в известном месте секции, и таким образом массив нельзя использовать совместно с другими общими библиотеками. В итоге компоновщик урегулирует ситуацию с этой релокацией. С другой стороны, поскольку global_arr может быть использован (или перезаписан) другой общей библиотекой, уже динамический загрузчик должен будет разобраться со ссылкой к global_arr. [3]

Наконец, давайте взглянем на отсылку к global_func:

  int t = global_func(argc);24:       8b 45 ec                mov    -0x14(%rbp),%eax27:       89 c7                   mov    %eax,%edi29:       b8 00 00 00 00          mov    $0x0,%eax2e:       e8 00 00 00 00          callq  33 <main+0x1e>33:       89 45 fc                mov    %eax,-0x4(%rbp)

Поскольку операнд callq тоже RIP-относителен, релокация R_X86_64_PC32 работает здесь аналогично размещению фактического относительного сдвига к global_func в операнд.

В заключение отметим, что благодаря малой модели кода компилятор воспринимает все данные и код будущей программы как доступные через 32-битный сдвиг, и тем самым для доступа к всевозможным объектам создает простой и эффективный код.

Большая модель кода


Перевод цитаты из man gcc на тему большой модели кода:

-mcmodel=large
Генерация кода для большой модели: Эта модель не делает предположений относительно адресов и размеров секций.

Пример дизассемблированного кода main, скомпилированного при помощи не-PIC большой модели:

int main(int argc, const char* argv[]){  15: 55                      push   %rbp  16: 48 89 e5                mov    %rsp,%rbp  19: 48 83 ec 20             sub    $0x20,%rsp  1d: 89 7d ec                mov    %edi,-0x14(%rbp)  20: 48 89 75 e0             mov    %rsi,-0x20(%rbp)    int t = global_func(argc);  24: 8b 45 ec                mov    -0x14(%rbp),%eax  27: 89 c7                   mov    %eax,%edi  29: b8 00 00 00 00          mov    $0x0,%eax  2e: 48 ba 00 00 00 00 00    movabs $0x0,%rdx  35: 00 00 00  38: ff d2                   callq  *%rdx  3a: 89 45 fc                mov    %eax,-0x4(%rbp)    t += global_arr[7];  3d: 48 b8 00 00 00 00 00    movabs $0x0,%rax  44: 00 00 00  47: 8b 40 1c                mov    0x1c(%rax),%eax  4a: 01 45 fc                add    %eax,-0x4(%rbp)    t += static_arr[7];  4d: 48 b8 00 00 00 00 00    movabs $0x0,%rax  54: 00 00 00  57: 8b 40 1c                mov    0x1c(%rax),%eax  5a: 01 45 fc                add    %eax,-0x4(%rbp)    t += global_arr_big[7];  5d: 48 b8 00 00 00 00 00    movabs $0x0,%rax  64: 00 00 00  67: 8b 40 1c                mov    0x1c(%rax),%eax  6a: 01 45 fc                add    %eax,-0x4(%rbp)    t += static_arr_big[7];  6d: 48 b8 00 00 00 00 00    movabs $0x0,%rax  74: 00 00 00  77: 8b 40 1c                mov    0x1c(%rax),%eax  7a: 01 45 fc                add    %eax,-0x4(%rbp)    return t;  7d: 8b 45 fc                mov    -0x4(%rbp),%eax}  80: c9                      leaveq  81: c3                      retq

И вновь полезно взглянуть на релокации:

Relocation section '.rela.text' at offset 0x62c18 contains 5 entries:  Offset          Info           Type           Sym. Value    Sym. Name + Addend000000000030  001500000001 R_X86_64_64       0000000000000000 global_func + 000000000003f  001100000001 R_X86_64_64       0000000000000000 global_arr + 000000000004f  000300000001 R_X86_64_64       0000000000000000 .data + 1a000000000005f  001200000001 R_X86_64_64       0000000000000340 global_arr_big + 000000000006f  000300000001 R_X86_64_64       0000000000000000 .data + 31080

Поскольку нет необходимости делать предположения относительно размеров секций кода и данных, большая модель кода довольно унифицирована и одинаковым образом определяет доступ ко всем данным. Давайте вновь взглянем на global_arr:

  t += global_arr[7];3d:       48 b8 00 00 00 00 00    movabs $0x0,%rax44:       00 00 0047:       8b 40 1c                mov    0x1c(%rax),%eax4a:       01 45 fc                add    %eax,-0x4(%rbp)

Двум командам необходимо получить желаемое значение из массива. Первая команда размещает абсолютный 64-битный адрес в rax, который, как мы скоро увидим, окажется адресом global_arr, тогда как вторая команда загружает слово из (rax) + 0х1с в eax.

Так что давайте сфокусируемся на команде по адресу 0x3d, movabs, абсолютной 64-битной версии mov в архитектуре х64. Она может забросить полную 64-битную константу прямо в регистр, и так как в нашем дизассемблированном коде значение этой константы равно нулю, за ответом нам придется обратиться к таблице релокаций. В ней мы найдем абсолютную релокацию R_X86_64_64 для операнда по адресу 0x3f, со следующим значением: размещение значения символа плюс слагаемого обратно в сдвиг. Другими словами, rax будет содержать абсолютный адрес global_arr.

А что насчет функции вызова?

  int t = global_func(argc);24:       8b 45 ec                mov    -0x14(%rbp),%eax27:       89 c7                   mov    %eax,%edi29:       b8 00 00 00 00          mov    $0x0,%eax2e:       48 ba 00 00 00 00 00    movabs $0x0,%rdx35:       00 00 0038:       ff d2                   callq  *%rdx3a:       89 45 fc                mov    %eax,-0x4(%rbp)

За уже знакомым нам movabs следует команда call, которая вызывает функцию по адресу в rdx. Достаточно взглянуть на соответствующую релокацию чтобы понять насколько она похожа на доступ к данным.

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

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

Средняя модель кода


Как и ранее, давайте взглянем на перевод цитаты из man gcc:

-mcmodel=medium
Генерация кода для средней модели: Программа скомпонована в нижних двух гигабайтах адресного пространства. Здесь же расположены и малые символы. Символы размера большего, чем задано через -mlarge-data-threshold, попадают в больше данные или секции bss и могут находиться выше двух гигабайт. Программы могут быть скомпонованы и статически, и динамически.

Аналогично малой модели кода, средняя модель предполагает что весь код скомпонован в двух нижних гигабайтах. Тем не менее, данные разделены на предполагаемо скомпонованные в нижних двух гигабайтах малые данные и неограниченные по размещению в памяти большие данные. Данные попадают в категорию больших при превышении ими предела, по определению равного 64 килобайтам.

Также важно отметить, что при работе со средней моделью кода для больших данных по аналогии с секциями .data и .bss создаются специальные секции: .ldata и .lbss. Это не так важно в призме темы текущей статьи, однако я собираюсь немного от нее отклониться. Детальнее с данным вопросом можно ознакомиться в ABI.

Теперь становится понятно, почему в примере появились те массивы _big: они нужны средней модели для интерпретации больших данных, которыми они, при размере в 200 килобайт каждый, и являются. Ниже можно ознакомиться с результатом дизассемблирования:

int main(int argc, const char* argv[]){  15: 55                      push   %rbp  16: 48 89 e5                mov    %rsp,%rbp  19: 48 83 ec 20             sub    $0x20,%rsp  1d: 89 7d ec                mov    %edi,-0x14(%rbp)  20: 48 89 75 e0             mov    %rsi,-0x20(%rbp)    int t = global_func(argc);  24: 8b 45 ec                mov    -0x14(%rbp),%eax  27: 89 c7                   mov    %eax,%edi  29: b8 00 00 00 00          mov    $0x0,%eax  2e: e8 00 00 00 00          callq  33 <main+0x1e>  33: 89 45 fc                mov    %eax,-0x4(%rbp)    t += global_arr[7];  36: 8b 05 00 00 00 00       mov    0x0(%rip),%eax  3c: 01 45 fc                add    %eax,-0x4(%rbp)    t += static_arr[7];  3f: 8b 05 00 00 00 00       mov    0x0(%rip),%eax  45: 01 45 fc                add    %eax,-0x4(%rbp)    t += global_arr_big[7];  48: 48 b8 00 00 00 00 00    movabs $0x0,%rax  4f: 00 00 00  52: 8b 40 1c                mov    0x1c(%rax),%eax  55: 01 45 fc                add    %eax,-0x4(%rbp)    t += static_arr_big[7];  58: 48 b8 00 00 00 00 00    movabs $0x0,%rax  5f: 00 00 00  62: 8b 40 1c                mov    0x1c(%rax),%eax  65: 01 45 fc                add    %eax,-0x4(%rbp)    return t;  68: 8b 45 fc                mov    -0x4(%rbp),%eax}  6b: c9                      leaveq  6c: c3                      retq

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

Средняя модель кода это умелый компромисс между большой и малой моделями. Навряд ли код программы окажется слишком велик [4], так что подвинуть его сверх лимита в два гигабайта могут разве что статически скомпонованные в него большие куски данных, возможно как часть некоего объемного табличного поиска. Так как средняя модель кода отсеивает такие объемные куски данных и особым образом их обрабатывает, то вызовы кодом функций и малых символов будут так же эффективны, как и в малой модели кода. Только обращения к большим символам, по аналогии с большой моделью, потребуют от кода воспользоваться полным 64-битным методом большой модели.

Малая PIC-модель кода


Теперь давайте посмотрим на PIC варианты моделей кода, и как и раньше мы начнем с малой модели. [5] Ниже можно видеть пример кода, скомпилированного через малую PIC-модель:

int main(int argc, const char* argv[]){  15:   55                      push   %rbp  16:   48 89 e5                mov    %rsp,%rbp  19:   48 83 ec 20             sub    $0x20,%rsp  1d:   89 7d ec                mov    %edi,-0x14(%rbp)  20:   48 89 75 e0             mov    %rsi,-0x20(%rbp)    int t = global_func(argc);  24:   8b 45 ec                mov    -0x14(%rbp),%eax  27:   89 c7                   mov    %eax,%edi  29:   b8 00 00 00 00          mov    $0x0,%eax  2e:   e8 00 00 00 00          callq  33 <main+0x1e>  33:   89 45 fc                mov    %eax,-0x4(%rbp)    t += global_arr[7];  36:   48 8b 05 00 00 00 00    mov    0x0(%rip),%rax  3d:   8b 40 1c                mov    0x1c(%rax),%eax  40:   01 45 fc                add    %eax,-0x4(%rbp)    t += static_arr[7];  43:   8b 05 00 00 00 00       mov    0x0(%rip),%eax  49:   01 45 fc                add    %eax,-0x4(%rbp)    t += global_arr_big[7];  4c:   48 8b 05 00 00 00 00    mov    0x0(%rip),%rax  53:   8b 40 1c                mov    0x1c(%rax),%eax  56:   01 45 fc                add    %eax,-0x4(%rbp)    t += static_arr_big[7];  59:   8b 05 00 00 00 00       mov    0x0(%rip),%eax  5f:   01 45 fc                add    %eax,-0x4(%rbp)    return t;  62:   8b 45 fc                mov    -0x4(%rbp),%eax}  65:   c9                      leaveq  66:   c3                      retq

Релокации:

Relocation section '.rela.text' at offset 0x62ce8 contains 5 entries:  Offset          Info           Type           Sym. Value    Sym. Name + Addend00000000002f  001600000004 R_X86_64_PLT32    0000000000000000 global_func - 4000000000039  001100000009 R_X86_64_GOTPCREL 0000000000000000 global_arr - 4000000000045  000300000002 R_X86_64_PC32     0000000000000000 .data + 1b800000000004f  001200000009 R_X86_64_GOTPCREL 0000000000000340 global_arr_big - 400000000005b  000300000002 R_X86_64_PC32     0000000000000000 .data + 31098

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

Как можно заметить, нет никакой разницы между сгенерированным для статичных массивов кодом и кодом в не-PIC случае. Это один из плюсов архитектуры x64: благодаря IP-относительному доступу к данным, мы бонусом получаем PIC, по крайней мере до тех пор пока не требуется внешний доступ к символам. Все команды и релокации остаются теми же, так что обрабатывать их лишний раз не нужно.

Интересно обратить внимание на глобальные массивы: стоит напомнить, что в PIC глобальные данные должны проходить через GOT, поскольку в какой-то момент их могут хранить, или пользоваться ими, общие библиотеки [6]. Ниже можно видеть код для доступа к global_arr:

  t += global_arr[7];36:   48 8b 05 00 00 00 00    mov    0x0(%rip),%rax3d:   8b 40 1c                mov    0x1c(%rax),%eax40:   01 45 fc                add    %eax,-0x4(%rbp)

Интересующая нас релокация это R_X86_64_GOTPCREL: позиция входа символа в GOT плюс слагаемое, минус сдвиг за применение релокации. Другими словами, в команду патчится относительный сдвиг между RIP (следующей инструкции) и зарезервированного для global_arr в GOT слота. Таким образом, в rax в команду по адресу 0x36 размещается фактический адрес global_arr. Следом за этим шагом идет сброс ссылки на адрес global_arr плюс сдвиг на его седьмой элемент в eax.

Теперь давайте взглянем на вызов функции:

  int t = global_func(argc);24:   8b 45 ec                mov    -0x14(%rbp),%eax27:   89 c7                   mov    %eax,%edi29:   b8 00 00 00 00          mov    $0x0,%eax2e:   e8 00 00 00 00          callq  33 <main+0x1e>33:   89 45 fc                mov    %eax,-0x4(%rbp)

В ней есть релокация операнда callq по адресу 0x2e, R_X86_64_PLT32: адрес PLT входа для символа плюс слагаемое, минус сдвиг за применение релокации. Другими словами, callq должен корректно вызывать PLT трамплин для global_func.

Обратите внимание, какие неявные предположения совершает компилятор: что к GOT и PLT можно получить доступ через RIP-относительную адресацию. Это будет важно при сравнении этой модели с другими PIC-вариантами моделей кода.

Большая PIC-модель кода


Дизассемблирование:

int main(int argc, const char* argv[]){  15: 55                      push   %rbp  16: 48 89 e5                mov    %rsp,%rbp  19: 53                      push   %rbx  1a: 48 83 ec 28             sub    $0x28,%rsp  1e: 48 8d 1d f9 ff ff ff    lea    -0x7(%rip),%rbx  25: 49 bb 00 00 00 00 00    movabs $0x0,%r11  2c: 00 00 00  2f: 4c 01 db                add    %r11,%rbx  32: 89 7d dc                mov    %edi,-0x24(%rbp)  35: 48 89 75 d0             mov    %rsi,-0x30(%rbp)    int t = global_func(argc);  39: 8b 45 dc                mov    -0x24(%rbp),%eax  3c: 89 c7                   mov    %eax,%edi  3e: b8 00 00 00 00          mov    $0x0,%eax  43: 48 ba 00 00 00 00 00    movabs $0x0,%rdx  4a: 00 00 00  4d: 48 01 da                add    %rbx,%rdx  50: ff d2                   callq  *%rdx  52: 89 45 ec                mov    %eax,-0x14(%rbp)    t += global_arr[7];  55: 48 b8 00 00 00 00 00    movabs $0x0,%rax  5c: 00 00 00  5f: 48 8b 04 03             mov    (%rbx,%rax,1),%rax  63: 8b 40 1c                mov    0x1c(%rax),%eax  66: 01 45 ec                add    %eax,-0x14(%rbp)    t += static_arr[7];  69: 48 b8 00 00 00 00 00    movabs $0x0,%rax  70: 00 00 00  73: 8b 44 03 1c             mov    0x1c(%rbx,%rax,1),%eax  77: 01 45 ec                add    %eax,-0x14(%rbp)    t += global_arr_big[7];  7a: 48 b8 00 00 00 00 00    movabs $0x0,%rax  81: 00 00 00  84: 48 8b 04 03             mov    (%rbx,%rax,1),%rax  88: 8b 40 1c                mov    0x1c(%rax),%eax  8b: 01 45 ec                add    %eax,-0x14(%rbp)    t += static_arr_big[7];  8e: 48 b8 00 00 00 00 00    movabs $0x0,%rax  95: 00 00 00  98: 8b 44 03 1c             mov    0x1c(%rbx,%rax,1),%eax  9c: 01 45 ec                add    %eax,-0x14(%rbp)    return t;  9f: 8b 45 ec                mov    -0x14(%rbp),%eax}  a2: 48 83 c4 28             add    $0x28,%rsp  a6: 5b                      pop    %rbx  a7: c9                      leaveq  a8: c3                      retq

Релокации:

Relocation section '.rela.text' at offset 0x62c70 contains 6 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000027 00150000001d R_X86_64_GOTPC64 0000000000000000 _GLOBAL_OFFSET_TABLE_ + 9
000000000045 00160000001f R_X86_64_PLTOFF64 0000000000000000 global_func + 0
000000000057 00110000001b R_X86_64_GOT64 0000000000000000 global_arr + 0
00000000006b 000800000019 R_X86_64_GOTOFF64 00000000000001a0 static_arr + 0
00000000007c 00120000001b R_X86_64_GOT64 0000000000000340 global_arr_big + 0
000000000090 000900000019 R_X86_64_GOTOFF64 0000000000031080 static_arr_big + 0

В этот раз различия между большими и малыми данными все еще не имеют значения, поэтому мы сфокусируемся на static_arr и global_arr. Но прежде необходимо обратить внимание в этом коде на пролог, ранее мы не сталкивались с подобным:

1e: 48 8d 1d f9 ff ff ff    lea    -0x7(%rip),%rbx25: 49 bb 00 00 00 00 00    movabs $0x0,%r112c: 00 00 002f: 4c 01 db                add    %r11,%rbx

Ниже можно прочесть перевод связанной с этим цитаты из ABI:

В малой модели кода ко всем адресам (включая GOT) можно получить доступ через предоставленную архитектурой AMD64 IP-относительную адресацию. Именно поэтому нет нужды в явном указателе GOT и таким образом нет нужды в устанавливающем его прологе в функции. В большой и средней моделях кода необходимо определить регистр для хранения адреса GOT в независимых от расположения объектах, поскольку AMD64 ISA не поддерживает мгновенное перемещение размером больше чем 32 бит.

Давайте посмотрим на то, как описанный выше пролог вычисляет адрес GOT. Во-первых, команда по адресу 0x1e загружает свой собственный адрес в rbx. Затем совместно с релокацией R_X86_64_GOTPC64 совершается абсолютный 64-битный шаг в r11. Эта релокация означает следующее: берем адрес GOT, вычитаем перемещаемый сдвиг и добавляем слагаемое. Наконец, команда по адресу 0x2f складывает оба результата вместе. Итогом становится абсолютный адрес GOT в rbx. [7]

Зачем же мучиться с вычислением адреса GOT? Во-первых, как отмечено в цитате, в большой модели кода мы не можем предполагать, что 32-битного RIP-относительного сдвига будет достаточно для адресации GOT, из-за чего нам и требуется полный 64-битный адрес. Во-вторых, мы все еще хотим работать с PIC-вариацией, так что мы не можем попросту поместить абсолютный адрес в регистр. Скорее сам адрес должен быть вычислен относительно RIP. Для этого и нужен пролог: он совершает 64-битное RIP-относительное вычисление.

В любом случае, раз у нас в rbx теперь есть адрес GOT, давайте посмотрим на то как получить доступ к static_arr:

  t += static_arr[7];69:       48 b8 00 00 00 00 00    movabs $0x0,%rax70:       00 00 0073:       8b 44 03 1c             mov    0x1c(%rbx,%rax,1),%eax77:       01 45 ec                add    %eax,-0x14(%rbp)

Релокация первой команды это R_X86_64_GOTOFF64: символ плюс слагаемое минус GOT. В нашем случае это относительный сдвиг между адресом static_arr и адресом GOT. Следующая инструкция добавляет результат в rbx (абсолютный адрес GOT) и сбрасывает ссылку со сдвигом по 0x1c. Для простоты визуализации такого вычисления ниже можно ознакомиться с псевдо-C примером:

// char* static_arr// char* GOTrax = static_arr + 0 - GOT;  // rax now contains an offseteax = *(rbx + rax + 0x1c);   // rbx == GOT, so eax now contains                             // *(GOT + static_arr - GOT + 0x1c) or                             // *(static_arr + 0x1c)

Обратите внимание на интересный момент: адрес GOT используется как привязка к static_arr. Обычно GOT не содержит в себе адрес символа, и так как static_arr не является внешним символом, нет причин хранить его внутри GOT. Тем не менее, в данном случае GOT используется как привязка к относительной адресу символа секции данных. Этот адрес, который кроме всего прочего не зависит от расположения, можно найти полным 64-битным сдвигом. Компоновщик в состоянии урегулировать эту релокацию, так что модифицировать секцию кода во время загрузки нет необходимости.

Но что насчет global_arr?

  t += global_arr[7];55:       48 b8 00 00 00 00 00    movabs $0x0,%rax5c:       00 00 005f:       48 8b 04 03             mov    (%rbx,%rax,1),%rax63:       8b 40 1c                mov    0x1c(%rax),%eax66:       01 45 ec                add    %eax,-0x14(%rbp)

Этот код несколько длиннее, а релокация отличается от обычной. По сути, GOT используется здесь более традиционным образом: релокация R_X86_64_GOT64 для movabs лишь говорит функции разместить сдвиг в GOT, там где в rax расположен адрес global_arr. Команда по адресу 0x5f берет адрес global_arr из GOT и помещает его в rax. Следующая команда сбрасывает ссылку на global_arr[7] и помещает значение в eax.

Теперь давайте взглянем на ссылку кода для global_func. Вспомним что в большой модели кода мы не могли делать предположений относительно размера секций кода, так что нам следует полагать что даже для доступа к PLT нам потребуется абсолютный 64-битный адрес:

  int t = global_func(argc);39: 8b 45 dc                mov    -0x24(%rbp),%eax3c: 89 c7                   mov    %eax,%edi3e: b8 00 00 00 00          mov    $0x0,%eax43: 48 ba 00 00 00 00 00    movabs $0x0,%rdx4a: 00 00 004d: 48 01 da                add    %rbx,%rdx50: ff d2                   callq  *%rdx52: 89 45 ec                mov    %eax,-0x14(%rbp)

Интересующая нас релокация это R_X86_64_PLTOFF64: адрес PLT входа для global_func минус адрес GOT. Результат размещается в rdx, куда затем помещается rbx (абсолютный адрес GOT). В итоге мы получаем адрес PLT входа для global_func в rdx.

Обратите внимание что вновь GOT используется как привязка, на этот раз для обеспечения независящей от адреса отсылки к сдвигу PLT входа.

Средняя PIC-модель кода


Наконец, мы разберем сгенерированный для средней PIC-модели код:

int main(int argc, const char* argv[]){  15:   55                      push   %rbp  16:   48 89 e5                mov    %rsp,%rbp  19:   53                      push   %rbx  1a:   48 83 ec 28             sub    $0x28,%rsp  1e:   48 8d 1d 00 00 00 00    lea    0x0(%rip),%rbx  25:   89 7d dc                mov    %edi,-0x24(%rbp)  28:   48 89 75 d0             mov    %rsi,-0x30(%rbp)    int t = global_func(argc);  2c:   8b 45 dc                mov    -0x24(%rbp),%eax  2f:   89 c7                   mov    %eax,%edi  31:   b8 00 00 00 00          mov    $0x0,%eax  36:   e8 00 00 00 00          callq  3b <main+0x26>  3b:   89 45 ec                mov    %eax,-0x14(%rbp)    t += global_arr[7];  3e:   48 8b 05 00 00 00 00    mov    0x0(%rip),%rax  45:   8b 40 1c                mov    0x1c(%rax),%eax  48:   01 45 ec                add    %eax,-0x14(%rbp)    t += static_arr[7];  4b:   8b 05 00 00 00 00       mov    0x0(%rip),%eax  51:   01 45 ec                add    %eax,-0x14(%rbp)    t += global_arr_big[7];  54:   48 8b 05 00 00 00 00    mov    0x0(%rip),%rax  5b:   8b 40 1c                mov    0x1c(%rax),%eax  5e:   01 45 ec                add    %eax,-0x14(%rbp)    t += static_arr_big[7];  61:   48 b8 00 00 00 00 00    movabs $0x0,%rax  68:   00 00 00  6b:   8b 44 03 1c             mov    0x1c(%rbx,%rax,1),%eax  6f:   01 45 ec                add    %eax,-0x14(%rbp)    return t;  72:   8b 45 ec                mov    -0x14(%rbp),%eax}  75:   48 83 c4 28             add    $0x28,%rsp  79:   5b                      pop    %rbx  7a:   c9                      leaveq  7b:   c3                      retq

Релокации:

Relocation section '.rela.text' at offset 0x62d60 contains 6 entries:  Offset          Info           Type           Sym. Value    Sym. Name + Addend000000000021  00160000001a R_X86_64_GOTPC32  0000000000000000 _GLOBAL_OFFSET_TABLE_ - 4000000000037  001700000004 R_X86_64_PLT32    0000000000000000 global_func - 4000000000041  001200000009 R_X86_64_GOTPCREL 0000000000000000 global_arr - 400000000004d  000300000002 R_X86_64_PC32     0000000000000000 .data + 1b8000000000057  001300000009 R_X86_64_GOTPCREL 0000000000000000 global_arr_big - 4000000000063  000a00000019 R_X86_64_GOTOFF64 0000000000030d40 static_arr_big + 0

Для начала давайте уберем вызов функции. Аналогично малой модели, в средней модели мы предполагаем, что ссылки на код не превышают пределов 32-битного RIP сдвига, следовательно, код для вызова global_func полностью аналогичен такому же коду в малой PIC-модели, равно как и для случаев массивов малых данных static_arr и global_arr. Поэтому мы сфокусируемся на массивах больших данных, но сначала поговорим о прологе: здесь он отличается от пролога большой модели данных.

1e:   48 8d 1d 00 00 00 00    lea    0x0(%rip),%rbx

Это весь пролог: чтобы при помощи релокации R_X86_64_GOTPC32 разместить GOT адрес в rbx, потребовалась всего одна команда (по сравнению с тремя в большой модели). В чем же разница? Дело в том, что так как в средней модели GOT не является частью секций больших данных, мы предполагаем его доступность в рамках 32-битного сдвига. В большой модели мы не могли совершать подобные предположения, и были вынуждены пользоваться полным 64-битным сдвигом.

Вызывает интерес тот факт, что код для доступа к global_arr_big похож на такой же код в малой PIC-модели. Это происходит по той же причине, почему пролог средней модели короче пролога большой модели: мы полагаем доступность GOT в рамках 32-битной RIP-относительной адресации. Действительно, к самому global_arr_big нельзя получить такой доступ, но этот случай все равно покрывает GOT, так как фактически global_arr_big в нем и находится, причем в виде полного 64-битного адреса.

Ситуация, тем не менее, отличается для static_arr_big:

  t += static_arr_big[7];61:   48 b8 00 00 00 00 00    movabs $0x0,%rax68:   00 00 006b:   8b 44 03 1c             mov    0x1c(%rbx,%rax,1),%eax6f:   01 45 ec                add    %eax,-0x14(%rbp)

Этот случай похож на большую PIC-модель кода, поскольку тут мы все же получаем абсолютный адрес символа, которого нет в самом GOT. Так как это большой символ, о котором нельзя предположить его нахождение в нижних двух гигабайтах, нам, как и в большой модели, требуется 64-битный PIC сдвиг.

Примечания:


[1] Не стоит путать модели кода с 64-битными моделями данных и моделями памяти Intel, все это разные темы.

[2] Важно помнить: собственно команды создает компилятор, и режимы адресации фиксируются именно на этом шаге. Компилятор не может знать в какие программы или общие библиотеки попадет объектный модуль, одни могут оказаться малыми, а другие большими. Компоновщику известен размер итоговой программы, но уже слишком поздно: компоновщик может лишь патчить сдвиг команд релокацией, а не менять сами команды. Таким образом, соглашение модели кода должно быть подписано программистом на этапе компиляции.

[3] Если что-то осталось непонятным, ознакомьтесь со следующей статьей.

[4] Тем не менее, объемы постепенно растут. Когда я в последний раз проверял Debug+Asserts билд Clang, он почти достигал одного гигабайта, за что во многом спасибо автогенерируемому коду.

[5] Если вы еще не знаете как работает PIC (как в целом, так и в частности для архитектуры x64), самое время ознакомиться со следующими статьями по теме: раз и два.

[6] Таким образом, компоновщик не может самостоятельно разрешить ссылки, и вынужден переложить обработку GOT на динамический загрузчик.

[7] 0x25 0x7 + GOT 0x27 + 0x9 = GOT



Подробнее..

Перевод Как рендерится кадр DOOM Ethernal

11.09.2020 14:12:59 | Автор: admin


Вступление


Doom Eternal не нуждается в отдельном представлении: это прямой преемник Doom 2016, разработанный благодаря седьмой итерации id Tech, внутреннего движка студии id Software. В свое время меня поразило и высокое качество визуальной составляющей Doom 2016, и простота и элегантность технических решений. В этом отношении Doom Eternal превосходит своего предшественника во многих областях, и некоторые из них достойны детального разбора. В этой аналитической статье я постараюсь обсудить их все.

Мой анализ вдохновлен трудом Adrian Courrges про Doom 2016 (перевод). Я считаю, что подобные работы позволяют взглянуть на подходы к решению некоторых проблем рендеринга AAA-проектов и тем самым становятся превосходными обучающими материалами. В этом анализе я планирую обсудить общие особенности и не погружаться слишком глубоко в тонкости каждого способа и прохода рендеринга. Кроме того, некоторые проходы в Doom Eternal почти не отличаются от своих аналогов в Doom 2016 и уже были разобраны в труде Adrian Courrges, поэтому я могу их пропустить.

Хочу особым образом отметить строго обучающий характер текущей статьи. Я никоим образом не поддерживаю реверс-инжиниринг продуктов с целью кражи интеллектуальной собственности или иного злого умысла. Если вы еще не успели сыграть в Doom Eternal, можете не беспокоиться: я разбирал лишь самое начало игры, поэтому спойлеры вам не грозят.

Итак, приступим.

С выходом id Tech 7 переход движка с OpenGL на Vulkan API позволил разработчикам эффективнее работать с особенностями текущего поколения графических процессоров, например несвязанными ресурсами (bindless resources).

Один кадр в Doom Eternal




Выше мы можем видеть близкую к началу секцию игры: интерьер с несколькими противниками и объемным освещением. По аналогии с его предшественником, процессом визуализации в Doom Eternal заведует прямой рендеринг, однако если Doom 2016 вынужден проводить прямой рендеринг совместно с G-буферизацией отражающих поверхностей, в нашем случае буфер не используется и прямой рендеринг берет на себя все задачи.

Уход от мегатекстур


С выходом созданной на движке id Tech 5 игры Rage мир познакомился с концептом реализации текстур под названием мегатекстуры. Этот метод применяется в Doom 2016 и на каждый кадр он рендерит так называемую виртуальную текстуру с информацией о видимых текстурах. Виртуальная текстура анализируется в следующем кадре, чтобы определить какие текстуры следует подгрузить с диска. Однако у мегатекстур есть очевидная проблема: как только текстура попадает поле зрения, подгружать ее уже поздновато, поэтому на первых нескольких кадрах после появления текстура выглядит размыто. С выходом id Tech 7 разработчики отказались от такого метода.

Скиннинг через графический процессор


Обычно еще до отрисовки каких-либо текстур и шейдинга оценку скиннинга проводит вершинный шейдер. Скиннинг id Tech 7 проводится заранее вычислительным шейдером с записью итоговых вершин в буфер. Благодаря такому подходу вершинному шейдеру больше не нужны данные скиннинга, и так как при каждом проходе геометрии он больше не проводится, в итоге перестановки шейдеров случаются реже.

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

По ссылке можно ознакомиться с отличной статьей о скиннинге через вычислительный шейдер за авторством Jnos Turnszki.

Полезно также отметить, что в Doom Eternal используется интересный вид кеширования Alembic Cache, сравнимый с сильно сжатым обратно воспроизводимым видео. В таких кешах хранится запеченная анимация для выдачи и разжатия в ходе исполнения программы. Цитируя технический анализ Digital Foundry, Alembic Cache применяется в широком диапазоне анимаций, начиная с масштабных кинематографичных сцен и заканчивая крохотными щупальцами на полу. Особенно удобен такой подход для анимаций со сложностями реализации через скиновую анимацию, например для органики и симуляции тканей. Если вас заинтересовала эта технология, рекомендую ознакомиться с презентацией Axel Gneiting на Siggraph 2014.

Карты теней


Следующим этапом является рендеринг теней, и подход к генерации их карт на первый взгляд у id Tech 7 и его предшественника не отличается.

Как можно видеть ниже, тени рендерятся в большую текстуру глубиной 24 бита и размером 4096 на 8196 пикселей, местами различаясь по уровню качества. Текстура не меняется между кадрами, и согласно презентации Devil is in the Details на Siggraph 2016, статичная геометрия кешируется в карте теней, чтобы не перерисовать ее для каждого кадра. Идея сама по себе проста: нам не нужно обновлять тени до тех пор, пока перед источником света не начнется движение, и таким образом мы можем объявить кешированную карту теней: обычную карту со статичной геометрией, так как мы полагаем, что геометрия не меняется. Если в конусе обзора движется динамический объект, кешированная карта теней копируется в основную, и поверх этого перерисовывается динамическая геометрия. Такой подход позволяет не перерисовывать всю сцену в конусе обзора при каждом ее обновлении. Естественно, при смещении света всю сцену придется перерисовать с нуля.

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

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



Скорость и предварительный проход обработки глубины


Начиная с оружия игрока, в целевую глубину последовательно рендерятся непрозрачная, статическая и динамическая геометрии. Обычно, чтобы при потенциальном пересечении геометрий не делать лишних вычислений пиксельных шейдеров, проводится предварительный проход обработки глубины с добавлением результата в буфер. Поскольку перерисовка пикселей при их пересечении создает лишние перерасчеты и в итоге негативно сказывается на производительности, важность такого подхода становится неоценима. Благодаря предварительному проходу глубины пиксельный шейдер прямого освещения может исключить лишние пиксели, сравнив их с буфером глубины еще до собственно вычислений, и тем самым сэкономить ценные ресурсы.


Оружие игрока


Статические объекты


Динамические объекты

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



Z-иерархическая глубина


Следующий шаг это генерация иерархической mip-цепи буфера глубины: эта цепь похожа на mip карту, но вместо усреднения четырех соседних пикселей берет их максимальное значение. Такой подход часто используется в графике для множества задач, например для ускорения отражений и отбрасывания прегражденной геометрии. В нашем случае mip-цепь отбрасывает освещение и декальные текстуры, о которых мы поговорим позднее. В последнее время mip-генерацию проводят за один проход, с записью сразу в несколько mip-ов, но в Doom Eternal запись все еще ведется отдельно для каждого mip.



Декали сеток


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

Чтобы добиться такого положительного результата, следующий проход геометрии рендерит идентификаторы каждой декали в восьмибитную текстуру. В дальнейшем, при наложении теней, мы сэмплим текстуру и через идентификаторы получаем связанные с каждым вызовом отрисовки матрицы проекций. Матрица проецирует координаты пикселя из пространства мира в пространство текстур, а затем эти координаты используются для семплирования декали и ее слияния с материалом поверхности. Этот прием невероятно быстр в своем исполнении и открывает художникам широкий простор для работы с множеством декалей. Так как идентификаторы рендерятся в восьмибитную текстуру, потенциально в одной сетке может быть до 255 декалей.

Единственным условием для всего этого является привязка всех декальных текстур к процессам при отрисовке сеток. Благодаря полностью несвязанному процессу рендеринга разработчики могут связывать все декальные текстуры разом и динамически индексировать их в шейдере. Так как разработчики пользуются этим методом при реализации еще нескольких приемов в игре, подробнее о несвязанном процессе рендеринга мы поговорим позже.

Ниже мы можем видеть сетку декальных текстур. Для удобства визуализации идентификаторы покрашены в разные цвета.



Отбрасывание света и декалей


Свет в Doom Eternal полностью динамичен, и одновременно в область обзора может попадать до нескольких сотен источников. Кроме того, как мы уже отметили ранее, декали в игре имеют большое значение, например в том же Doom 2016 число декалей перевалило за тысячи. Все это требует особого подхода к отбрасыванию лишнего, иначе производительность не выдержит тяжести пиксельных шейдров.

В Doom 2016 использовался процессорный вариант кластерного отбрасываения света: свет и декали собирались в конусообрзаные фроксели, которые затем считывались в ходе шейдинга через определения индекса кластера из позиции пикселя. Размер каждого кластера составлял 256 пикселей и для сохранения квадратной формы логарифмически делился на 24 сегмента. Такой прием вскоре переняли многие другие разработчики, и похожие методы встречаются, например, в Detroit: Become Human и Just Cause.

Учитывая рост числа источников динамического освещения (сотни) и декалей (тысячи), процессорной кластеризации отбрасывания освещения в Doom Eternal уже не хватало, так как воксели становились слишком грубыми. В итоге для id Tech 7 разработчики придуман иной подход, и через исполняемые на различных этапах вычислительные шейдеры создали программный растеризатор. Сначала декали и свет связываются в гексаэдр (шестигранник) и передаются в вычислительный растеризатор, откуда вершины проецируются в экранное пространство. Затем второй вычислительный шейдер обрезает треугольники по границам экрана и собирает их в тайлы размером 256 на 256 пикселей. Одновременно с этим по аналогии с кластерным отбрасыванием отдельные элементы источников света и декалей записываются во фроксели, после чего следующий вычислительный шейдер проводит похожую процедуру под тайлы 32 на 32 пикселя. В каждом тайле прошедшие тест на глубину элементы помечаются в битовое поле. Последний вычислительный шейдер переводит битовые поля в список источников света, которые в итоге используются при проходе освещения. Что характерно, индексы элементов все еще записываются в трехмерные фроксели размером 256 на 256 пикселей по аналогии с кластерным подходом. В местах со значительным прерыванием глубины, для определения числа источников света в каждом тайле сравнивается минимальное значение и нового списка источников света, и старого списка кластерных источников.

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

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

Преграждение окружающего света в экранном пространстве


Преграждение окружающего света вычисляется в половинном разрешении вполне стандартным путем: сначала 16 случайных лучей исходят из позиции каждого пикселя в полусфере, а затем при помощи буфера глубины определяются пересекающиеся с геометрией лучи. Чем больше лучей пересекает геометрии, тем больше будет преграждение. Эта техника называется преграждение направленного света в экранном пространстве (Screen Space Directional Occlusion), или SSDO, и подробное его описание за авторством Yuriy O`Donnell можно прочитать по ссылке. Вместо традиционного хранения значений преграждения в одноканальной текстуре, направленное преграждение хранится в трехкомпонентной текстуре, а итоговое преграждение определяется через скалярное произведение над нормалью пикселя.

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



Непрозрачный прямой проход


В этом проходе многие элементы наконец встают на свои места. В отличие от Doom 2016, здесь все рендерится напрямую через несколько массивных мегашейдеров. Во всей игре предположительно около 500 процессорных состояний и дюжина макетов дескрипторов. Сначала рендерится оружие игрока, потом динамические объекты, и затем статические. Обратите внимание, что порядок не особо-то и важен, ведь благодаря препроходу глубины мы уже получили буфер глубины, и он может заранее исключать не соответствующие глубине пиксели.


Оружие игрока


Динамические объекты


Первый набор статических объектов


Второй набор статических объектов

У большинства движков AAA-игр графы шейдеров и особенности статических шейдеров позвляют разработчикам возможность креативно подходить к работе со всевозможными материалами и поверхностями, и каждый материал, каждая поверхность ведет к созданию своего собственного уникального шейдера. В результате мы сталкиваемся с невероятным многообразием перестановок шейдеров для всех возможных комбинаций особенностей движка. Однако id Tech сильно отличается от других AAA-проектов: он комбинирует почти все материалы и особенности во всего лишь несколько массивных мегашейдеров. Такой подход позволяет графическим процессам жестче объединять геометрию, что в свою очередь положительно сказывается на производительности. Позже мы еще это обсудим.

Несвязанные ресурсы


Стоит обратить внимание, что весь процесс формирования графики содержит в себе идею несвязанных ресурсов. Это значит, что вместо привязки размытия, отражений, неровности текстуры перед каждым вызовом отрисовки, весь список текстур в сцене привязывается разом. Доступ к текстурам из списка осуществляется в шейдере динамически через переданные шейдеру константами индексы. Таким образом, через любой вызов отрисовки можно получить любую текстуру, что открывает путь множеству оптимизаций, об одной из которых мы сейчас и поговорим.



Динамическое слияние вызовов отрисовки


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

Здесь в игру вступает самая интересная технология idTech 7: динамическое слияние вызовов отрисовки. Она полагается на архитектуру несвязанных ресурсов и обобщенную память вершин, и в итоге значительно уменьшает число вызовов отрисовки и время работы процессора. Еще до начала какого-либо рендеринга вычислительный шейдер динамически создает непрямой буфер индексов для эффективного слияния геометрий из невзаимосвязанных сеток в единый непрямой вызов отрисовки. Без несвязанных ресурсов добиться слияния вызовов не получилось бы, поскольку оно работает с геометриями с несовпадающими свойствами материалов. В дальнейшем воспользоваться динамическим буфером индекса можно будет вновь, как для препрохода глубины, так и для препрохода освещения.

Отражения


Чаще всего для создания отражений экранного пространства вычислительный шейдер использует алгоритм raymarching. Алгоритм испускает из пикселя луч в мировое пространство в сторону отражения, которое зависит от неровности отражающей поверхности. Точно так же дело обстояло в Doom 2016, там как часть прямого прохода записывался небольшой G-буфер. Однако в Doom Eternal уже никакого G-буфера нет, и даже отражения экранного пространства вычисляются не в вычислительном шейдере по отдельности, а сразу в прямом шейдере. Интересно узнать, насколько такое отклонение в пиксельном шейдере влияет на производительность, поскольку создается ощущение, что ценой повышенной нагрузки на регистр разработчики пытались снизить количество целей рендера и как следствие сократить нагрузку на пропускную способность памяти.

Зачастую когда в текстуре экранного пространства нет необходимой информации, у соответствующих эффектов возникают артефакты визуализации. Чаще всего это заметно при отражениях экранного пространства в случаях, когда невидимые отражаемые объекты не могут отражаться. Проблема обычно решается традиционным подходом, через статичные кубические карты отражений в качестве резерва.



Но так как мегатекстуры в Doom Eternal больше не используются, в резервных текстурах тоже нет нужды.

Частицы


Симуляция


В Doom Eternal часть процессорной симуляции частиц ложится на плечи вычислительных шейдерв, поскольку у некоторых систем частиц есть зависимости от информации экранного пространства, например буфера глубины для симуляции столкновений. Тогда как другие системы частиц могут прогоняться в кадре сразу и вычисляться асинхронно, таким симуляциям предварительно необходимы данные препрохода глубины. Что характерно, в отличие от традиционной шейдерной симуляции частиц, здесь симуляция ведется через выполнение последовательности команд из хранящегося в вычислительном шейдере буфера. Каждый поток шейдера прогоняет все команды, среди которых может быть по несколько kill, emit или модификаций параметра частицы. Все это похоже на записанную в шейдере виртуальную машину. Я многое не понимаю в тонкостях работы такой симуляции, но основан подход на презентации Brandon Whitney The Destiny Particle Architecture на Siggraph 2017. Метод в презентации очень похож на описанный мною выше и используется во множестве других игр. Например, я уверен, что похожим образом в Unreal Engine 4 работает система симуляции частиц Niagara.

Освещение


По аналогии с Doom 2016 и описанному на Siggraph 2016 методу, разрешение частиц освещения отделено от собственно разрешения экрана, что дает разработчикам управлять разрешением каждой системы частиц в зависимости от качества, размера экрана и прямого управления. Для низкочастотных эффектов освещение можно предоставить в значительно более низком разрешении почти без потери в качестве по сравнению с, например, искрами, которым требуется высокое разрешение. Освещение и доминирующее направление света хранятся в двух атласах размером 2048 на 2048 пикселей, оба они доступны для каждого прохода благодаря несвязанным ресурсам, как и любая другая текстура. В дальнейшем для рендера частиц простая геометрия отрисовывается через сэмплинг этих атласов.


Увеличенный фрагмент атласа освещения.

Небо и рассеяние


Теперь мы поговорим про объемное освещение. Его генерация состоит из четырех проходов и начинается с создания 3D LUT текстуры для атмосферы неба через raymarching сквозь само небо в сторону источника света.



С первого раза можно не понять, что именно отображает текстура на картинке, но если мы повернем ее на 90 градусов и растянем по горизонтали, все станет ясно: перед нами рассеяние атмосферы. Поскольку оно более вариативно по вертикали чем по горизонтали, то и разрешение по вертикали больше. Атмосфера представлена сферой, поэтому горизонтальное вращение обычно называется долготой, а вертикальное широтой. Атмосферное рассеяние вычисляется полусферой и покрывает 360 градусов долготы и 180 градусов широты верхней части сферы. Для покрытия различных расстояний до наблюдателя в LUT текстуре содержится 32 сегмента глубины, и вместо перевычисления данных неба в каждом кадре процесс распределяется на 32 кадра.



Благодаря LUT текстуре, следующий проход вычисляет рассеяние света на наблюдаемый фроксель по аналогии с кластерным преграждением света в меньшем масштабе. Пронаблюдать несколько сегментов, от ближнего к дальнему, можно ниже.



В третьем проходе данные рассеяния для каждой клетки множатся в каждую последующую клетку в сторону обзора и пишутся в новую 3D текстуру.

В итоге поверх рендеририуемого изображения через сэмплинг только что сгенерированной 3D текстуры на основе глубины пикселей ставится объемное освещение.


До


После

Итоговое видимое небо рендерится на полусфере если попадает в обзор. В этой сцене небо в обзор не попало, но ниже можно взглянуть на пример рендера неба в сцене на открытом воздухе.



Прозрачность


По аналогии с Doom 2016, прозрачность рендерится прямым проходом после непрозрачной геометрии при наличии данных о рассеянии света. Текстура сцены при этом теряет в разрешении (downsamples), а для имитации прозрачности на основе гладкости поверхности подбирается подходящий mip-уровень. Данные о рассеянии света помогают создать изнутри поверхности визуально хорошее рассеяние.

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


Для прозрачности теряют в разрешении только имеющие к ней отношение пиксели.

Пользовательский интерфейс


Обычно последним проходом в кадре становится пользовательский интерфейс. Как это обычно и происходит, интерфейс рендерится во вторичную с полным разрешением LDR (восьмибитную) цель рендера, и цвет предварительно умножается на альфа-канал. В ходе тональной компрессии интерфейс накладывается на HDR текстуру. Обычно заставить интерфейс работать с остальным HDR контентом кадра не так-то просто, но в Doom Eternal при тональной компресии интерфейс волшебным образом скалируется и выглядит естественно на фоне прочего 3D контента.



Постобработка


Первым при постобработке выступает размытость: этот двухпроходный эффект считывает данные из текстуры цвета и кастомизированного буфера скорости. Первый проход набирает четыре образца вертикальной оси, второй четыре по горизонтальной. Затем образцы цвета смешиваются в соответствии движением пикселя. Чтобы исключить смазывание, кастомизирвоанный буфер скорости должен убедиться в отсутствии ореолов, и что оружие игрока исключено из процесса.

Далее идет целевое воздействие: эта RG (двухцветная) текстура форматом 1 на 1 содержит в себе среднее значение освещения всей сцены и вычисляется путем последовательного уменьшения разрешения цветовой текстуры и получения средней освещенности группы пикселей. Чаще всего такой прием используется для имитации привыкания человеческого глаза к резкой смене окружающей яркости. Также средняя освещенность используется при вычислении воздействия в ходе тональной компрессии.



После всего этого вычисляется Bloom. Этого эффекта маловато в нашем примере и широко визуализировать его не получится, но достаточно знать, что вычисление ведется путем получения данных о цвете выше определенного предела и последовательного уменьшения разрешения текстуры для ее размытия.

Затем тональная компрессия объединяет все эффекты. Один-единственный вычислительный шейдер делает следующее:

  • Применяет искажение
  • Рендерит поверх Bloom текстуру
  • Вычисляет виньетирование, грязь на камере, хроматическую аберрацию, отблеск от линз и множество других эффектов
  • Получает значение воздействия на основе средней освещенности
  • Дает тональной компрессии распределить HDR цвета по корректным диапазонам как для LDR, так и для HDR через кастомный оператор тональной компрессии.

И наконец, сверху накладывается интерфейс.

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



Заключение


Наш поверхностный разбор одного кадра Doom Eternal подошел к концу, хоть я и уверен, что не затронул несколько влияющих на внешний вид игры моментов. На мой взгляд, Doom Eternal это невероятный успех в техническом плане, и в будущем id Software сможет еще больше повысить планку. Команда разработчиков успешно продемонстрировала нам, как разумный подход и эффективное планирование помогли создать высококачественную игру, и я верю, что это отличный пример для подражания, равно как и обучающий материал. С нетерпением жду будущих разработок id Software.

Rip and tear, until it is done.

Справочные материалы


Подробнее..

Перевод В чём главные проблемы Intel

29.01.2021 14:10:10 | Автор: admin


Оглядываясь назад, моя статья по поводу назначения нового исполнительного директора Intel в 2013 году оказалась чрезмерно оптимистичной. Одно название чего стоит: Возможность для Intel. В реальности вышло не так за эти годы у Intel ничего не получилось, никакими возможностями она не воспользовалась.

Откуда мы знаем, что не получилось? Во-первых, спустя восемь лет Intel опять назначает нового директора (Пэт Гелсингер), но не вместо того, о котором я писал (Брайан Кржанич), а вместо его преемника (Боб Свон). Очевидно, в то самое окно возможностей компания на самом деле не попала. И теперь уже встаёт вопрос выживания компании. И даже вопрос национальной безопасности Соединённых Штатов Америки.

Проблема 1: мобильные устройства


Вторая причина, по которой заголовок 2013 года был чрезмерно оптимистичным, заключается в том, что к тому моменту Intel уже попала в серьёзную беду. Вопреки своим заявлениям, компания слишком сосредоточилась на скорости CPU и слишком пренебрежительно отнеслась к энергопотреблению, поэтому не смогла сделать процессор для iPhone, и, несмотря на годы попыток, не смогла попасть на Android.

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

Когда речь идёт о миллиардных инвестициях в строительство фабрик следующего поколения, то вы или преуспеваете на рынке, или банкрот. Intel смогла сохранить миллиардные доходы благодаря революции в другой отрасли: облачных вычислениях.

Проблема 2: успех на серверах


Intel захватила этот рынок не так давно. Изначально на нём доминировали интегрированные компании, такие как Sun, с соответствующими ценами, но благодаря взрыву продаж персональных компьютеров Intel быстро улучшала производительность и снижала цены CPU, особенно по отношению к производительности. Конечно, ПК не дотягивали до надёжности интегрированных серверов, но на рубеже веков Google поняла, что масштаб и сложность услуг делают невозможным создание действительно надёжного стека. Решением стали отказоустойчивые серверы с горячей заменой вышедших из строя компонентов. Это позволило строить дата-центры на относительно дешёвых процессорах x86.



В течение двух следующих десятилетий подход Google приняли все крупные ЦОДы, так что x86 стала архитектурой по умолчанию для серверов. Основную выгоду из этого извлекла Intel, поскольку именно она делала лучшие процессоры x86, особенно для серверных приложений. Это связано как с собственным дизайном Intel, так и с её великолепными фабриками. AMD иногда угрожала действующему лидеру, но только в ноутбуках низкого уровня, а вовсе не в дата-центрах.

Таким образом, Intel избежала судьбы Microsoft в постдесктопную эпоху: Microsoft пролетела не только мимо мобильных устройств, но и мимо серверов, которые работают под управлением Linux, а не Windows. Конечно, компания как может поддерживает Windows и на компьютерах (через Office), и на серверах (через Azure). Однако всё выходит наоборот: то, что недавно подпитывало рост компании, становится концом Windows, поскольку Office переходит в облако с работой на всех устройствах, а Azure переходит на Linux. В обоих случаях Microsoft пришлось признать, что их власть теперь не в контроле над API, а в обслуживании уже существующих клиентов в новом масштабе.

В упомянутой статье о перспективах Intel упоминался аналогичный стратегический разворот. Intel долго опиралась на интеграцию проектирования и производства. В мобильную эпоху x86 вслед за Windows навсегда уходит в нишевый десктопный рынок. Но всё равно была возможность сохранить бизнес, если начать принимать заказы на производство от сторонних клиентов.

Большинство компаний сами не выпускают чипы. Они создают дизайн и отдают на завод. AMD, Nvidia, Qualcomm, MediaTek, Apple ни у кого нет собственных заводов. Безусловно, это имеет смысл: производство полупроводников, возможно, самая капиталоёмкая отрасль в мире, так что AMD, Qualcomm и другие хотят заниматься более прибыльными проектами с более высокой маржой.

Однако проектирование микросхем становится всё более стандартным. Почти все чипы основаны на архитектуре ARM. Оплатив лицензию, компании вроде Apple могут создавать собственные модификации и заказывать их производство. Дизайн немножко уникален, но в мобильных устройствах это не самое принципиальное. Здесь никогда не будет доминировать единый дизайн от одного разработчика, как Intel доминировала на десктопном рынке.

С другой стороны, именно производственные мощности становятся более дефицитными и, следовательно, более ценными. На самом деле в мире только четыре крупных производственных компании: Samsung, GlobalFoundries, Taiwan Semiconductor Manufacturing Company (TSMC) и Intel. Только четыре компании могут создавать чипы, которые сегодня установлены в каждом мобильном устройстве, а завтра будут установлены вообще везде.

Огромный спрос, дефицит компонентов, высочайшие барьеры для входа. Получается, сейчас отличное время для производства микросхем. Это потенциально отличное время для Intel. Ведь из этих четырёх компаний она самая продвинутая, со значительным отрывом. Единственная проблема заключается в том, что Intel всегда видит себя дизайнерской компанией.

Кстати, моя рекомендация не означает отказ от x86, я добавил в сноске:

Конечно, они продолжат проектировать x86, но это будет не единственный их бизнес, а со временем даже и не основной.

На самом деле, бизнес x86 оказался слишком прибыльным, чтобы пойти на такой радикальный шаг. Это именно та проблема, которая ведёт к разрушению. Да, Intel избежала судьбы Microsoft, но при этом не испытала сильнейшей финансовой боли, которая необходима как стимул для такой кардинальной трансформации бизнеса (например, только после краха рынка памяти в 1984 году Энди Гроув в Intel решил полностью сосредоточиться на производстве процессоров).

Проблема 3: производство




Пока Intel тормозила с принятием решений, за последнее десятилетие модульно-ориентированная TSMC получила огромные заказы на мобильные чипы и установила лучшее в мире оборудование по производству микросхем от ASML. В модульной экосистеме все компании получают часть прибыли от растущего мобильного рынка и в результате этого бума производственные мощности TSMC превзошли Intel.

Это угрожает Intel по нескольким фронтам:

  • Intel окончательно потеряла рынок маков, в том числе из-за выдающейся производительности нового чипа M1. Но важно отметить причины такой производительности это не только дизайн Apple, но и 5-нм техпроцесс TSMC.
  • Десктопные процессоры AMD теперь быстрее, чем у Intel, и чрезвычайно конкурентоспособны на серверах. Опять же, преимущество AMD отчасти связано с улучшением дизайна, но не менее важным является производство по 7-нм процессу TSMC.
  • Крупные облачные провайдеры всё больше инвестируют в разработку собственных чипов. Например, Amazon уже выпустила вторую версию процессора Graviton ARM, на котором будет работать таймлайн твиттера. Одно из преимуществ Graviton его архитектура, а другое ну, вы уже поняли производство компанией TSMC по тому же 7-нм техпроцессу (который конкурирует с наконец-то запущенным 10-нм техпроцессом Intel).

Короче говоря, Intel теряет долю на рынке, ей угрожает AMD на x86-серверах и облачные компании типа Amazon с собственными процессорами. И я даже не упомянул других специализированных решений, таких как приложения на GPU для машинного обучения, которые разрабатывает Nvidia и производит Samsung.

Что делает эту ситуацию настолько опасной для Intel, так это проблема масштаба, о которой я упоминал выше. Компания уже пролетела мимо мобильного рынка, и хотя серверные процессоры обеспечили рост, необходимый для инвестиций в производство за последнее десятилетие, но Intel не может позволить себе потерять объём денежного потока именно в тот момент, когда должна произвести максимальные инвестиции в своей истории.

Проблема 4: TSMC


К сожалению, это ещё не самое худшее. На следующий день после назначения нового директора Intel компания TSMC объявила впечатляющие финансовые результаты и, что более важно, прогнозы капитальных инвестиций на 2021 год, от Bloomberg:

TSMC спровоцировала глобальный рост акций полупроводниковых компаний, когда объявила о планах капитальных инвестиций в этом году в размере целых 28 миллиардов долларов ошеломляющей суммы, направленной на расширение технологического лидерства и строительство завода в Аризоне для обслуживания ключевых американских клиентов.

Это огромная сумма инвестиций, которая только упрочит лидерство TSMC.

Предполагаемый рост финансирования привёл к тому, что производители оборудования для производства микросхем хлынули из Нью-Йорка в Токио. Капитальные расходы TSMC от 25 до 28 миллиардов долларов в 2021 году гораздо выше прошлогодних 17,2 миллиардов. Около 80% вложений направят на передовые технологии производства CPU, то есть TSMC ожидает резкого роста бизнеса по производству передовых микросхем. Аналитики предполагают, что после серии внутренних технологических сбоев Intel передаст производство на аутсорсинг таким компаниям, как TSMC.

Так оно и есть. Вероятно, в данный момент Intel уступила лидерство в производстве микросхем. Компания сохраняет высокую маржу в проектировании CPU и может исключить угрозу AMD, передав производство передовых чипов на аутсорсинг TSMC. Но это лишь увеличит лидерство TSMC и никак не поможет решить другие проблемы Intel.

Проблема 4: геополитика


Уязвимости Intel не единственное, о чём стоит беспокоиться. В прошлом году я писал о чипах и геополитике:

Международный статус Тайваня, как говорится, сложный. Собственно, как и отношения между Китаем и США. Всё это накладывается одно на другое и создаёт совершенно новые осложнения, делая ситуацию ещё более запутанной.

Ну а география, напротив, простая и понятная:



Как видите, Тайвань находится недалеко от китайского побережья. Рядом Южная Корея, родина Samsung, которая тоже производит чипы самого высокого класса. Соединённые Штаты по другую сторону Тихого океана. Есть передовые фабрики Intel в Орегоне, Нью-Мексико и Аризоне, но Intel производит чипы только для собственных интегрированных вариантов использования.

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

Если вы занимаетесь военным стратегическим планированием в США, это большая проблема. Ваша задача не предсказывать войны, а планировать действия, которые могут произойти при неудачном стечении обстоятельств, то есть если вдруг случится война между США и Китаем. И в этом планировании серьёзной проблемой является размещение заводов TSMC и Samsung в пределах лёгкой досягаемости китайских ракет.

Буквально несколько дней назад компания TSMC официально объявила о строительстве 5-нм завода в Аризоне. Да, сегодня это передовые технологии, но завод откроется только в 2024 году. Тем не менее это почти наверняка будет самая передовая фабрика в США, которая выполняет сторонние заказы. Надеюсь, к моменту открытия Intel превзойдёт её возможности.

Однако заметим, что интересы Intel и США не совпадают. Первая заботится о платформе x86, а США нужны передовые фабрики общего назначения на её территории. Иными словами, у Intel всегда в приоритете дизайн, а у США производство.

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

Решение 1: раздел


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

Главное, что нужно понять о микроэлектронике что маржа в дизайне гораздо выше. Например, у Nvidia валовая маржа 60-65%, в то время как у TSMC, которая производит для неё микросхемы, ближе к 50%. Как я уже отмечал выше, маржа Intel традиционно ближе к Nvidia благодаря интеграции дизайна и производства, поэтому собственные чипы всегда будут приоритетом для её производственного подразделения. От этого пострадает обслуживание потенциальных клиентов и гибкость в выполнении сторонних заказов, а также эффективность привлечения лучших поставщиков (что ещё больше снизит маржу). Здесь ещё и вопрос доверия: готовы ли конкуренты делиться своими разработками, особенно если Intel уделяет приоритетное внимание собственному дизайну?

Единственный способ решить эту проблему приоритетов выделить производственный бизнес Intel в отдельную компанию. Да, потребуется время, чтобы создать отделы обслуживания клиентов, не говоря уже об огромной библиотеке строительных блоков открытой интеллектуальной собственности, которая сильно упрощает работу с TSMC. Но автономный производственный бизнес получит главный и самый мощный стимул для осуществления этой трансформации стремление выжить.

Решение 2: субсидии


Выделение производственного бизнеса в отдельную компанию также открывает двери для закачки государственных денег в этот сектор. Сейчас для США нет смысла субсидировать Intel. Компания на самом деле не строит то, что нужно США, и у компании явно проблемы с культурой и управлением, которые не решить просто денежными вливаниями.

Вот почему федеральная программа субсидирования должна действовать как гарантия покупки. Государство закупает определённое количество произведённых в США 5-нм процессоров по такой-то цене; определённое количество произведённых в США 3-нм процессоров по такой-то цене; определённое количество 2-нм процессоров и так далее. Это не только установит цели для производства Intel, но и подтолкнёт другие компании зайти на этот рынок. Возможно, вернутся в игру глобальные производственные компании или TSMC построит больше фабрик в США, а возможно, в нашем мире почти свободного капитала наконец появится стартап, готовый совершить революцию.

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

AMD представила серверные процессоры Ryzen Threadripper Pro, но они не будут продаваться в розницу

15.07.2020 12:10:08 | Автор: admin


Кроме десктопного рынка, AMD всерьёз рассчитывает захватить и серверный рынок. И вот вчера компания впервые анонсировала линейку процессоров для рабочих станций под новым брендом Ryzen Threadripper Pro. Однако следует отметить, что эти процессоры будут доступны только в составе готовых систем, и соответствующие потребительские материнские платы не будут выпускаться.

Набор продуктов от AMD в течение нескольких поколений включал процессоры Ryzen Pro и Ryzen Mobile Pro, в том числе варианты с поддержкой ECC. Можно было предположить, что в то время как у Ryzen был вариант Ryzen Pro, наиболее естественным вариантом для Threadripper будет линейка EPYC. Рынок серверов и рынок высокопроизводительных настольных компьютеров/рабочих станций всегда частично перекрывались, и до этого момента, если покупателю нужен был серверный дизайн, с ECC и проверкой программного обеспечения, он обращался к EPYC.

Сейчас AMD меняет положение вещей, выпуская Ryzen Threadripper Pro.

Процессоры Ryzen Threadripper Pro по функциям во многом соответствуют односокетным EPYC: восемь каналов памяти до DDR4-3200, 128 линий PCIe 4.0, поддержка RDIMM и LRDIMM, поддержка безопасного шифрования памяти, поддержка управляемости DASH и проверки согласованности образа операционной системы в рамках программы AMD Pro Business Ready.

Где Ryzen Threadripper Pro отличается, так это по количеству ядер, частотам и TDP. Судите сами.

AMD Ryzen Threadripper Pro
Ядра Базовая частота Турбо Чиплеты TDP DRAM
3995WX 64 / 128 2700 4200 8 + 1 280 Вт 8 x DDR4-3200
3975WX 32 / 64 3500 4200 4 + 1 280 Вт 8 x DDR4-3200
3955WX 16 / 32 3900 4300 2 + 1 280 Вт 8 x DDR4-3200
3945WX 12 / 24 4000 4300 2 + 1 280 Вт 8 x DDR4-3200

Существует также небольшая разница в поддержке DRAM TR Pro поддерживает до 2 ТБ, а EPYC поддерживает 4 ТБ. Все процессоры Ryzen Threadripper Pro выпускаются только для одного сокета.

У топового процессора 3995WX 64 ядра. Он выходит за рамки топового EPYC 7742 (225 Вт, 2,25 ГГц / 3,4 ГГц) и даже 7H12 (280 Вт, 2,6 ГГц / 3,3 ГГц), предлагая более высокую базовую частоту 2,7 ГГц и гораздо более высокую турбочастоту 4,2 ГГц для TDP 280 Вт.

Вот как выглядит сравнение Threadripper Pro, обычных Threadripper и Intel Xeon:



AMD говорит, что количество ядер и частотные конфигурации более оптимально удовлетворяют разные потребности лицензирования, то есть учитывают программное обеспечение с лицензиями на ядро (где рекомендуются высокочастотные модели с меньшим количеством ядер) или на сокет (где рекомендуется больше ядер).

Одним из интересных элементов Threadripper Pro является то, что он настроен только на OEM. Это означает, что покупателям нужно будет договариваться с Lenovo или другими компаниями, чтобы купить оборудование. На данный момент Lenovo собирается стать партнёром по запуску семейства TR Pro на семействе рабочих станций ThinkStation P620. Соответствующий анонс уже опубликован на официальном сайте.


ThinkStation P620

Lenovo будет предлагать P620 в различных вариантах, с объёмом памяти до 1 ТБ DRAM и двумя графическими процессорами RTX 8000 (или четырьмя графическими процессорами RTX 4000).

В Lenovo P620 процессор установлен в такой ориентации, чтобы помочь с воздушным потоком, но это также ограничивает гнездо только одним DIMM на канал, поэтому здесь поддержка максимум 1 ТБ памяти. Система будет использовать множество инноваций Lenovo ThinkStation, таких как легко заменяемые вентиляторы, приводы и тому подобное.



Задача P620 и подобного оборудования очень похожа на задачу EPYC заменить топовые рабочие станции и с одним, и с двумя процессорами. Lenovo планирует позиционировать P620 TR Pro для замены своих продуктов P520 (один сокет) и P720 (два сокета). Рабочая станция появится в продаже с конца сентября.

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

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

Это интересное решение AMD, поскольку Ryzen Threadripper Pro позиционируется против процессоров Intel серии Xeon W-3200 и Xeon W-2200. Некоторые из этих процессоров доступны в коробочном виде, а другие продаются потребителям в виде деталей, и для каждого есть ряд коммерческих материнских плат. Ответ AMD прост с их продуктовой линейкой они решили, что в ней нет места для новой категории розничных процессоров. Поэтому TR Pro и WRX80 пока будут доступны только для OEM-производителей. Если кто-то хочет купить TR Pro в розницу, сообщите об этом AMD.

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

До того как Intel запустила Xeon Scalable, она предлагала варианты своей линейки процессоров E5-2600 в качестве моделей для рабочих станций, таких как E5-2687W v2/v3/v4. Эти сокеты были совместимы с высококачественными настольными процессорами Intel без ECC или могли использоваться в серверных материнских платах с проверкой ECC.

После этого Intel выпустила семейство Xeon W-2100 на базе Skylake и предлагающее до 18 ядер с четырёхканальной памятью. Они работают на высокопроизводительном десктопном сокете LGA2066, но требуют специальных серверных материнских плат (со специальными серверными чипсетами). Эти CPU позже обновили до Xeon W-2200 на ядре Cascade Lake.

Вместе с тем, у Intel были процессоры Xeon W-3100 и Xeon W-3200 для сокета LGA3647, что позволяло использовать шестиканальную память и предложить до 28 ядер. Intel даже предложила специальную модель W-3175X с возможностью разгона.

Потом в 2020 году Intel добавила в линейку своих рабочих станций семейство Xeon W-1200, используя потребительский сокет LGA1200, но опять же с материнскими платами только на серверном чипсете. Эти W-1200 фактически заменяют процессоры E-2300, а семейство Xeon E было законсервировано в Xeon W.

Кроме того, у Intel есть Xeon Scalable Cascade Lake, который тоже широко используется на рабочих станциях.

Аргумент AMD здесь заключается в том, что TR Pro будет конкурировать со всеми предложениями Intel Xeon W. Там, где у Intel более 80 различных опций для различных сокетов, AMD предлагает только четыре, которые покроют большую часть рынка, плюс Ryzen Pro для нижнего класса рабочих станций.

Естественно, AMD считает, что они вышли победителем, и так же, как 64-ядерный Threadripper 3990X был противопоставляется двум процессорам Xeon 8280, и AMD сделала то же самое с 3995WX:



Сравнение производительности в различных программах (кликабельно):



AMD не будет публиковать официальные цены для своих новых процессоров, поскольку они выпускаются только для OEM, так что здесь практически невозможно сравнить производительность из расчёта на доллар.

Кроме того, AMD не выдаёт эти процессоры для тестирования представителям прессы (это вполне естественно, учитывая отсутствие материнских плат в продаже), предлагая попросить Lenovo насчёт рабочей станции P620.



Подробнее..

Опубликованы спецификации памяти DDR5

16.07.2020 10:19:49 | Автор: admin

DDR5: по четыре чипа памяти на банк, пятый для встроенной проверки ECC (on-die-ECC)

Отмечая важную веху в развитии компьютерной памяти, ассоциация JEDEC выпустила окончательную спецификацию следующего основного стандарта памяти DDR5 SDRAM. Последняя итерация стандарта DDR4 была основой развития ПК и серверов с конца 90-х. DDR5 ещё раз расширяет возможности памяти, удваивая и пиковую скорость, и объём памяти. Железо на новом стандарте ожидается в 2021 году, причем внедрение начнется на уровне серверов, а затем просочится на клиентские ПК и другие устройства.

Выпуск DDR5 первоначально планировавшийся в 2018 году, Сегодняшняя публикация спецификаций DDR5 немного отстаёт от первоначального графика JEDEC, но это не умаляет её важности. Как и каждая предыдущая итерация DDR, основное внимание для DDR5 снова сосредоточено на улучшении плотности памяти, а также скорости. JEDEC стремится удвоить и то, и другое, установив максимальную скорость памяти не менее 6,4 Гбит/с, в то время как ёмкость одного упакованного по полной модуля LRDIMM сможет достичь 2 ТБ.

Поколения JEDEC DDR
DDR5 DDR4 DDR3 LPDDR5
Макс. плотность одного ядра 64 Гбит 16 Гбит 4 Гбит 32 Гбит
Макс. размер UDIMM 128 ГБ 32 ГБ 8 ГБ N/A
Макс. скорость передачи 6,4 Гбит/с 3,2 Гбит/с 1,6 Гбит/с 6,4 Гбит/с
Кааналов 2 1 1 1
Ширина (Non-ECC) 64-бит (2x32) 64-бит 64-бит 16-бит
Банки
(Per Group)
4 4 8 16
Группы банков 8/4 4/2 1 4
Длина пакета BL16 BL8 BL8 BL16
Напряжение (Vdd) 1,1 В 1,2 В 1,5 В 1,05 В
Vddq 1,1 В 1,2 В 1,5 В 0,5 В

Рассчитанная на несколько лет (или десятилетий) DDR5 позволит использовать отдельные чипы памяти плотностью до 64 Гбит, что в 4 раза превышает максимальную плотность 16 Гбит DDR4. В сочетании со штабелированием, которое позволяет укладывать до 8 ядер (dies) в виде одного чипа, 40-элементный LRDIMM может достичь эффективного объема памяти 2 ТБ или 128ГБ для DIMM обычного дизайна.

Но объём памяти будет расти постепенно, а вот скорость возрастёт мгновенно. Запуск DDR5 произойдёт на скорости 4,8 Гбит/с, что примерно на 50% быстрее официальной максимальной скорости 3,2 Гбит/с DDR4. А в последующие годы текущая версия спецификации допускает скорость передачи данных до 6,4 Гбит/с. По мере технологического развития SK Hynix действительно может достичь своей цели DDR5-8400 в этом десятилетии.

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



Как и в других стандартах, таких как LPDDR4 и GDDR6, один DIMM разбивается на два канала. Вместо одного 64-битного канала данных на DIMM, DDR5 предлагает два независимых 32-битных канала данных (или 40-бит с проверкой ECC). Между тем длина пакета для каждого канала удваивается с 8 байт (BL8) до 16 байт (BL16), так что каждый канал будет доставлять 64 байта за операцию. Таким образом, DDR5 DIMM на идентичной скорости ядра будет выполнять две 64-байтовые операции за то время, которое требуется DDR4 DIMM для выполнения одной, удваивая эффективную пропускную способность.

Кроме изменения банков памяти, JEDEC представила слегка модифицированную шину, хотя она и работает с более жёсткими допусками.

Ключевой движущей силой здесь является введение выравнивания обратной связи принятия решений (decision feedback equalization, DFE). На очень высоком уровне DFE является средством уменьшения межсимвольных помех за счёт использования обратной связи от приёмника шины памяти для обеспечения лучшего выравнивания. А лучшее выравнивание, в свою очередь, позволяет обеспечить более чистый сигнал, чтобы шина повысила скорость передачи.

Наряду с изменением плотности ядра и скорости работы памяти, DDR5 также улучшает рабочие напряжения. По спецификациям, DDR5 будет работать с Vdd 1,1 В, по сравнению с 1,2 В для DDR4. Как и предыдущие обновления, это должно немного повысить энергоэффективность памяти. Кроме того, в модулях теперь появились встроенные регуляторы напряжения.

В DDR5 памяти DIMM по прежнему 288 контактов (пинов), но распиновка отличается.



Это напоминает переход от DDR2 к DDR3, где количество контактов также осталось одинаковым: 240 контактов.

Но конечно, DDR5 нельзя будет использовать в старых сокетах, даже если он вставится туда.

JEDEC устанавливает стандарт, который могут использовать его члены. Основные производители памяти, которые с самого начала участвовали в процессе разработки DDR5, уже разработали прототипы DIMM и теперь рассматривают возможность вывода на рынок первых коммерческих продуктов. Например, SK Hynix выпустила прототип DDR5 ещё в ноябре 2019 года.

Ожидается, что первые модули и материнские платы DDR5 выйдут через 12-18 месяцев после завершения разработки стандарта.



Подробнее..

AMD представила 18 новых процессоров для настольных ПК

22.07.2020 12:20:51 | Автор: admin

Процессоры 4-го поколения значительно производительнее аналогичных моделей AMD 3-го поколения, а также процессоров Intel Core (бенчмарки под катом)

Компания AMD, которая сегодня практически безраздельно владеет рынком настольных компьютеров, выпустила две новых линейки процессоров для десктопов. Это долгожданная 4000-я серия на архитектуре Zen2 (7нм) со встроенной графикой Vega, для стандартного сокета AM4:

  • шесть AMD Ryzen 4000 G-Series
    • + три новых Athlon 3000 G-Series
  • шесть AMD Ryzen 4000 Pro
    • + три новых Athlon 3000 Pro

Серия Pro полностью совпадает по техническим характеристикам со стандартной G-Series, так что в реальности речь идёт о девяти новых процессорах, из них шесть 4000-й серии и три Athlon 3000-й серии.

Поскольку процессоры подходят для существующих материнских плат с разъёмом AM4, на них огромный спрос среди тех, кто сам собирает себе компьютер и хочет сделать апгрейд. Разговоры о выпуске 4000-й серии шли с самой CES в январе. К сожалению, тут AMD всех разочаровала: в первое время новинки поставляются только интеграторам и OEM-партнёрам, розничные цены пока не объявлены. Придётся немного подождать.

Причиной для такого решения AMD назвала то, что 80% чипов в любом случае покупают OEM, а отказ от розничных продаж (20%) сильно упрощает планирование производства и логистику. Компания обещает скоро пустить их в розничную продажу.

Для начала список из шести новых Ryzen 4000 G-Series.

Ядер/потоков Базовая
частота
Турбо Юнитов GPU Частота GPU TDP
Ryzen 7 4700G 8 / 16 3600 4400 8 2100 65 Вт
Ryzen 7 4700GE 8 / 16 3100 4300 8 2000 35 Вт
Ryzen 5 4600G 6 / 12 3700 4200 7 1900 65 Вт
Ryzen 5 4600GE 6 / 12 3300 4200 7 1900 35 Вт
Ryzen 3 4300G 4 / 8 3800 4000 6 1700 65 Вт
Ryzen 3 4300GE 4 / 8 3500 4000 6 1700 35 Вт

В списке можно заметить некоторую закономерность: шесть процессоров идут тремя парами на 65 и 35Вт. В младшей версии просто обрезана частота и TDP, больше они не отличаются. Только в одном APU немного снижена ещё частота графики.

Все процессоры построены на 8-ядерной архитектуре Zen2 с 8 вычислительными юнитами Vega, как и мобильные Ryzen Mobile 4000, представленные ранее. Топовый Ryzen 7 4700G с TDP 65Вт задействует все 8 ядер и 8 вычислительных юнитов графики. Сам вычислительный модуль работает на базовой частоте 3,6ГГц (4,4ГГц турбо), а графика на сумасшедшей частоте 2,1ГГц.

В нижней части линейки Ryzen 3 4300G с четырьмя ядрами и шестью вычислительными юнитами Vega. Базовая частота 3,8ГГц, турбо 4,0ГГц. Шесть графических юнитов работают на частоте 1,7ГГц.

Все APU поддерживают память DDR4-3200, во всех выделено по восемь линий PCIe 3.0 для дополнительных видеокарт. Но это скорее пережиток мобильной версии чипа, для которой было принято такое техническое решение. На самом деле AMD предполагает, что встроенной графики в 4000-й серии в основном достаточно для большинства пользователей.

Бенчмарки от AMD


Дисклеймер: бенчмарки от AMD носят скорее рекламный характер и не являются объективными независимыми тестами.

Топовый Ryzen 4700G сравнивается с Intel Core i7-9700 в задачах на обработку медиа:



Сравнение в топовых играх с разрешением 1080p:



Такие же тесты на медиаобработку и игры для процессоров Ryzen 4600G и Intel Core i5-9500:





Наконец, сравнение Ryzen 3 4300G и Core i3-9100:





AMD сравнивает свои чипы с процессорами Intel 9-го поколения и утверждает, что в 10-м поколении у Intel нет особой прибавки, кроме немного повышенных тактовых частот, хотя на самом деле Intel добавила в 10-м поколении Hyper-Threading, так что количество потоков фактически возросло вдвое (два потока на каждое ядро), поэтому процессоры Intel 10-го поколения должны быть поближе по результатам к процессорам AMD, чем слегка устаревшие чипы 9-го поколения.

В общем, объективные выводы о производительности можно будет сделать только после публикации результатов независимых тестов.

Возможно, более объективным будет сравнение производительности 4000-й серии с собственными процессорами AMD предыдущих поколений.

Для начала, сравнение Ryzen 5 4600G с популярной моделью Ryzen 5 3400G.



Ryzen 5 4600G явно выигрывает за счёт перехода на новую архитектуру Zen2 с техпроцессом 7нм и улучшенные графические ядра Vega.

Бюджетный Ryzen3 4300G тоже немного выигрывает у Ryzen3 3200G.



В блоге AMD опубликована отдельная новость об апгрейде Adobe Premiere Pro, куда добавлена поддержка AMD GPU, так что видеообработка на новых процессорах выполняется с аппаратным ускорением. В блоге сравнивают производительность мобильной версии Ryzen 7 4800U в ноутбуке Lenovo Yoga Slim 7 при кодировании (экспорте) четырёхминутного видео Apple ProRes 4444 4K 60P QuickTime. Аппаратное и программное кодирование сравниваются с Ryzen 7 4700U и Ryzen 5 4500U.



Ryzen 4000 Pro


Процессоры Ryzen 4000 Pro отличаются словом Pro в названии, а маркировка оканчивается на 50, то есть Ryzen 7 Pro 4750GE, Ryzen 5 Pro 4650GE и так далее. Они позиционируются для корпоративных клиентов, поэтому оснащены несколькими дополнительными функциями по безопасности и управлению. Среди них:

  • полное шифрование памяти;
  • управление DASH;
  • стабильность ОС (запланировано 18 месяцев поддержки);
  • доступность процессоров в продаже (запланировано 24 месяца);
  • гарантированное качество и надёжность, продвинутая служба QA.


Новые Athlon


Наконец, вот список трёх новых Athlon 3000-й серии, изготовленных на старом ядре Zen+, вместе с их аналогами в линейке Pro.

Ядер/потоков Базовая
частота
Турбо Юнитов GPU Частота GPU TDP
Athlon 3000G
Athlon Gold 3150G 4 / 4 ? 3900 3 ? 65 Вт
Athlon Gold 3150GE 4 / 4 ? 3800 3 ? 35 Вт
Athlon Silver 3050GE 2 / 4 3400 - 3 ? 35 Вт
Athlon Pro 3000G
Athlon Gold Pro 3150G 4 / 4 3500 3900 3 1100 65 Вт
Athlon Gold Pro 3150GE 4 / 4 3300 3800 3 1100 35 Вт
Athlon Silver Pro 3125GE 2 / 4 3400 - 3 1100 35 Вт

Это первые процессоры с названиями Athlon Gold и Athlon Silver, то есть AMD вводит новый брендинг. По ним подробностей мало, цены тоже пока не опубликованы.

Будем надеяться, что AMD как можно раньше начнёт продажу всех этих процессоров в розницу.
Подробнее..

Intel застряла. Техпроцесс 7 нм откладывается до конца 2021 начала 2022 года

24.07.2020 12:09:40 | Автор: admin

Исполнительный директор Intel Боб Свон

Корпорация Intel опубликовала финансовый отчёт за IIкв. 2020года, в котором объявила об очередной задержке с переходом на техпроцесс 7нм. Планы отложили ещё на шесть месяцев, так что теперь внедрение 7нм планируется не раньше конца 2021-го начала 2022 года. В сумме отставание от внутренней дорожной карты Intel выросло до 12 месяцев.

Любопытно, что Intel планировала быстро перейти на 7нм, потому что испытывала проблемы с внедрением техпроцесса 10нм. Некоторые аналитики высказывают мнение, что в такой ситуации можно думать о переходе сразу на 5нм.

Исполнительный директор компании Боб Свон сказал инвесторам, что графический процессор для высокопроизводительных вычислений Ponte Vecchio выйдет не раньше, чем в конце 2021-го или начале 2022 года. Он должен стать первым 7-нанометровым чипом Intel.



7-нм процессор Intel для персональных компьютеров выйдет не ранее конца 2022-го начала 2023 года, а первый серверный процессор для дата-центров не ранее Iполугодия 2023года.

По словам Свона, компания выявила в своём 7-нм техпроцессе дефектный режим, это вызвало деградацию нормы техпроцесса. В результате Intel предусмотрела план на случай непредвиденных обстоятельств, включая использование сторонних фабрик по производству микросхем. Компания также будет использовать сторонние фабрики для будущих 7-нм графических процессоров Ponte Vecchio.

Ponte Vecchio производится с дизайном в виде чиплетов, и производство некоторых чиплетов будет передано на аутсорсинг сторонним подрядчикам.

Первые 7-нм серверные процессоры Granite Rapids тоже выйдут с опозданием, в 2023 году. Эта опасно на фоне того, что AMD по плану производит серверные чипы EPYC и планирует выпуск 5-нм процессоров Genoa до конца 2022 года.

Свон также сказал, что первые десктопные 10-нм процессоры Alder Lake выйдут во второй половине 2021 года.

Фактически, TSMC планирует освоить узлы 3нм в те же сроки, что и новый график Intel для 7нм.

Задержка с переходом 7 нм представляет собой очередную неудачу Intel, которая несколько лет испытывает проблемы с освоением процесса 10 нм. Эти задержки позволили AMD впервые в истории отвоевать у Intel лидерские позиции в разработке процессоров, что вызвало ценовую войну на рынке, поскольку Intel сражается с конкурентом x86, у которого лучшие технологии, не говоря уже о новых ARM-чипах Amazon Graviton 2, тоже основанных на 7-нм техпроцессе TSMC.

Apple недавно объявила, что переходит с чипов Intel на собственные 7-нм ARM-процессоры. А ведущий архитектор чипов, звезда Джим Келлер, недавно покинул компанию.


В июне 2020 года Intel объявила, что ведущий инженер микроэлектроники Джим Келлер покидает компанию

Intel заявила, что планирует увеличить поставки 10-нм чипов на 20% по сравнению с предыдущими прогнозами. Новый план Intel сосредоточен на получении еще одного полного узла производительности на базе текущего 10-нм узла, то есть 10-нм техпроцесс продлится дольше, чем планировалось, и облегчит переход на 7нм. Intel осуществила аналогичный трюк с 14-нм процессорами через серию + ревизий, которые добавили инкрементные улучшения производительности, вплоть до 14нм+++. Так что у неё есть послужной список успешных улучшений межузловых связей, которые помогут ей оставаться конкурентоспособной, пока она не исправит проблемы с 7-нм процессом.

Intel всегда использовала сторонние фабрики, которые в настоящее время составляют около 20% её производства, для низкомаржинальных, не связанных с процессорами продуктов. Новые планы Intel по более агрессивному использованию внешних фабрик могут привести к тому, что она будет использовать их для основной логики, такие как процессоры и графические процессоры, чего компания не делала в прошлом. В конечном счете, Intel может столкнуться со значительным снижением маржи, если передаст значительную часть высокодоходных продуктов на аутсорсинг третьим лицам. Полагаться на внешнего поставщика для производства передовых узлов очень рискованно, поскольку Intel придётся конкурировать с Apple, Nvidia и AMD в том числе за производственные мощности.

После публикации финансового отчёта акции Intel упали на 9%, акции AMD выросли на 6% на фоне недавнего анонса семейства десктопных CPU на архитектуре Zen2 (7нм) и впервые в истории обогнали акции Intel по номиналу ($61). Несмотря на отставание в цене акций, Intel почти в четыре раза опережает AMD по рыночной капитализации: $254млрд против $64млрд. У тайваньской TSMC рыночная стоимость $323млрд.

На первый взгляд кажется, что задержка Intel на шесть месяцев небольшая, но в реальности она будет иметь долгосрочный эффект домино. Она означает, что в течение нескольких лет Intel будет технологически отставать от AMD и Nvidia, пишет Reuters. Другими словами, в русле 7нм Intel уже неконкурентоспособна и может вернуться в полноценную борьбу только после перехода на 5нм.



Подробнее..

SK hynix представила первую в мире память DDR5 DRAM

06.10.2020 10:05:04 | Автор: admin
Корейская компания Hynix представила публике первую в своем роде оперативную память стандарта DDR5, о чем сообщается в официальном блоге компании.



По заявлению SK hynix, новая память обеспечивает скорость передачи данных в 4,8-5,6 Гбит/с на контакт. Это 1,8 раза больше, чем базовые показатели памяти предыдущего поколения DDR4. При этом производитель утверждает, что напряжение на планке уменьшено с 1,2 до 1,1 В, что, в свою очередь, повышает энергоэффективность модулей DDR5. Также была реализована поддержка коррекции ошибок ECC Error Correcting Code. Как утверждается, благодаря этой функции надежность работы приложений возрастёт в 20 раз по сравнению с памятью предыдущего поколения. Минимальный объем памяти платы заявлен на уровне 16 Гб, максимальный 256 Гб.

Новая память была разработана по спецификации стандарта ассоциации твердотельных технологий JEDEC, который опубликовали в 14 июля 2020 года. Согласно тогдашнему анонсу JEDEC, спецификация DDR5 поддерживает вдвое больший реальный канал, чем DDR4, то есть вплоть до 6,4 Гбит/с у DDR5 против имеющихся 3,2 Гбит/с у DDR4. При этом запуск стандарта будет плавным, то есть первые планки, как планировала ассоциация и что и показывает SK hynix, в базе быстрее только на 50% по сравнению с DDR4, то есть имеют канал в 4,8 Гбит/с

Согласно анонсу, компания готова перейти к массовому выпуску модулей памяти нового стандарта. Все подготовительные этапы и тесты, в то числе и тестирование со стороны производителей центральных процессоров, пройдены, и компания начнет активный выпуск и продажу нового типа памяти как только под нее появится соответствующее спецификациям оборудование. В разработке новой памяти активно участвовала компания Intel.



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

Джонхун О, исполнительный вице-президент и директор по маркетингу Sk hynix заявил:

SK hynix сосредоточится на быстрорастущем рынке серверов премиум-класса, укрепляя свои позиции в качестве ведущей компании в области серверной DRAM.

Основной этап выхода на рынок новой памяти рассчитан на 2021 год именно тогда спрос на DDR5 начнет расти и тогда же подойдет в продажу и оборудование, способное работать с новой памятью. В создании экосистемы для DDR5 вместе с SK hynix сейчас работают компании Synopsys, Renesas, Montage Technology и Rambus.

К 2022 году SK hynix прогнозирует захват памятью стандарта DDR5 доли в 10%, а к 2024 уже 43% рынка оперативной памяти. Правда, не уточняется, имеется в виду серверная память, или весь рынок, в том числе и десктопы, ноутбуки и прочие устройства.

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

Инсайд в новых процессорах Intel будет использоваться многочиповая конфигурация

08.10.2020 08:19:04 | Автор: admin
Согласно инсайду портала adoredtv.com, компания Intel перейдет к технологии многочиповой конфигурации к 2021-2022 году, а первым процессором с подобной компоновкой станет серверный чип линейки Sapphire Rapids. По данным, его тепловыделение составит около 400 Вт. Планируемый техпроцесс литографии 10 нм (+++) или SuperFin. Процессор будет оснащен 56(60) ядрами.



Однако это не самое главное, хотя анонс новой серверной линейки, которая придет на смену процессорам Sky Lake важный инфоповод. Но намного важнее то, что Intel сдается в своей борьбе с 7 и 5 нм техпроцессами и переходит к технологиям, которые уже используются их основным конкурентом компанией AMD. По всей видимости, проблемы с более мелкошаговой литографией оказались непреодолимы в обозримом будущем, а давление AMD только усиливается: уже сейчас красные обгоняют Intel в потребительском сегменте, фактически, на полтора-два поколения с учетом линейки Ryzen 5000, которая будет представлена уже сегодня, 8 октября.

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

Если говорить о конкретном процессоре на базе Sapphire Rapids, информацию о котором слили adoredtv, то этот процессор станет самой большой новинкой Intel со времен анонса серии Intel Core 8xxx.

Серия Sapphire Rapids будет использовать новое ядро архитектуры Golden Cove, которое придет на смену ядру Willow Cove.


Старый архитектурный роадмап Intel

Ожидается, что Golden Cove получит прирост в показателе межпроцессорного взаимодействия (IPC), в отличие от Willow Cove, у которого фактически было небольшое снижение по сравнению с архитектурой Sunny Cove.

Также планируется, что Intel внедрит в новых процессорах поддержку PCIe 5.0 и DDR5 (об анонсе первых серверных плашек памяти производства SK Hynix мы писали чуть раньше). В процессорах серии Sapphire Rapids планируется до 80 полос и CXL, что вполне конкурентно с IO AMD на ее платформе Rome. Последняя имеет больше полос, но только на скоростях PCIe 4.0. Еще Sapphire Rapids поддерживает память с частотой до 4800 МГц DDR5 и будет иметь поддержку восьмиканальной памяти.

Но, как обычно это бывает у Intel, тут есть пункт со звездочкой. Как в случае максимальной частоты на ядро (для CPU0), и с новыми процессорами существуют специфические ограничения. Описанный выше режим работы в PCIe 5.0 с 80 полосами будет возможен только на топовых моделях последних артикулов линейки; для всех прочих процессоров будет реализовано только 64 полосы.

Намного интереснее компоновка чипов на текстолите. Серверный Sapphire Rapids, скорее всего, будет реализован в виде четырех чипов на текстолитной подложке по 15 ядер на чип, активными из которых планируется только 14. Кроме того, в новых процессорах планируется реализация HBM2e на самом чипе объемом 64 Гб.

То есть, фактически, Intel планирует производить не просто многоядерный процессор, а полноценный чиплет с собственной встроенной памятью.

Подобный подход ожидался от AMD, но красные так и не перешли к полноценной реализации чиплета, ограничившись многочиповой конфигурацией самого процессора. Если Intel на самом деле сможет распаять память прямо на текстолите своего многочипового процессора, это будет рывок вперед и компания опять сможет занять условную позицию лидера в серверной гонке, ограничив поползновения AMD на этот практически монополизированный синими рынок.

Пару слов стоит сказать и о самом сливе инсайда техническому изданию. То, что Intel вяло потребовала удалить статью из-за неточностей в тексте именно с такой формулировкой а так же то, то что слив появился буквально за сутки большой презентации AMD указывает на две вещи.

Первое: Intel в ужасе и слив о новом процессоре тщательно спланированная акция по удержанию репутации компании среди фанатов и клиентов. Второе: презентация AMD, по всей видимости, будет разгромной, если маркетинговому отделу Intel в срочном порядке пришлось организовывать очень наивный и одновременно очень подробный слив о новых серверных процессорах компании наиболее важном сейчас для Intel сегменте рынка, потому что там они до сих пор неоспоримые лидеры и гегемоны.



Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru