Комментарии 81
Все эти постоянные расширения набора команд как бы намекают, что система изначально спроектирована предельно плохо и непродуманно. И давно пора уже заняться рефакторингом — засадить за работу теоретиков, чтобы те придумали нормальный набор команд; и потом реализовать его, не соблюдая требований совместимости.
Отдельная команда для получения случайного числа — это бред. Случайное число можно и нужно извлекать командой IN или через обращение к адресу памяти. Вообще, маса вещей м.б. реализована без расширения набора инструкций.
А ещё лучше — пересмотреть архитектуру компьютера. Если народу интересно — попробую написать статью, как это должно выглядеть.
А вот со случайным числом есть варианты. Но тоже согласен что это не должна быть отдельная команда.
Причины появления все новых и новых команд — устаревшая CISC-архитектура и обратная совместимость.
Рынок десктопов и серверов просто не примет что-либо, отличное от x86.
не потому ли из 80h порта уже нельзя прочитать записанное туда значение?
Cплошной FF возвращается. А ведь было удлобно пользоваться им для отладки.
- Согласно Intel Xeon Phi System Software Developer Guide, если на новом процессоре, не поддерживающем инструкции IN/OUT, попробовать их выполнить, произойдет исключение General Protection Fault (exception 0Dh, прерывание с вектором 0Dh=13). Дальнейшие действия зависят от того, как написана процедура обработки исключения: зависание, аварийное завершение, программная эмуляция порта и т. д.
- Возможность прочитать из порта 80h значение, которое ранее было туда записано, была связана с наличием по этому адресу одного из незадействованных страничных регистров Legacy DMA (i8237). В ряде платформ блок страничных регистров Legacy DMA занимает 16 байт по адресам 80h-8Fh, несмотря на то, что DMA-каналов только 7 (8 если считать канал, используемый для каскадирования). Именно в силу наличия доступных для чтения DMA Page Registers порт 80h был читаемым, ведь сама POST-карта не поддерживает чтение порта, только запись. Legacy DMA не стало немного раньше, чем IN/OUT.
Так в статье речь идёт о Xeon Phi, который вроде как не предлагается использовать в качестве основного
И давно пора уже заняться рефакторингом — засадить за работу теоретиков, чтобы те придумали нормальный набор команд; и потом реализовать его, не соблюдая требований совместимости.
А ещё лучше — пересмотреть архитектуру компьютера.
Предыдущие попытки закончились достаточно печально :)
С другой стороны, попробовать ещё раз никто не мешает — с удовольствием почитаем и прокомментируем ваш взгляд на предмет.
Просто камень это еще не все, нужна обвязка, а главное — софт. Ах да, и еще нужна жизнеспособная бизнес модель, что совершенно не коррелирует с качеством железа, к слову. Вот это-то и печально.
засадить за работу теоретиков, чтобы те придумали нормальный набор команд; и потом реализовать его, не соблюдая требований совместимости.
Что скажете об ARM?
Присоединяюсь к тем, кто ждёт статью.
Уже есть группа теоретиков которая ваяет новую идеальную систему комманд: RISC-V
https://riscv.org/
RISC-V: The Free and Open RISC Instruction Set Architecture
может в конце у них чего и получиться ...
Для времени своего появления это был потрясающий процессор. Однако, к сожалению, он начал эволюционировать, подобно большинству других процессоров — а в ходе любой эволюции накапливаются разные атавизмы.
Пожалуй, правильнее было бы иметь не 16 регистров, а больше. И в момент перехода в режим SWI/IRQ/FIQ надо было прятать не 2/2/7 регистров, а больше — например, 7/14/14 (в режимах IRQ и FIQ вообще не нужны регистры прежнего режима, все в тень).
А сейчас 32-битный процессор уже не тянет множества задач, нужно делать 64-битный. И команду процессора надо бы делать такой же. А значит, и систему команд надо переделывать.
Главной проблемой процессора ARM было то, что Acorn вела крайне глупую политику:
- Надо было лицензировать архитектуру, разрешив всем желающим за небольшие деньги создавать собственные клоны — и завоёвывать рынок с дешёвой стороны.
- Надо было рекламировать свои компьютеры как устойчивые к вирусам (операционка в ПЗУ закруывет основные направления вирусных атак).
- Надо было активнее продвигать сети, упирая на совместное использование HDD — это реально удобнее локальных дисков.
- Надо было не заморачиваться кооперативной многозадачностью, а портировать Unux — ну, хотя бы в виде совместимости с форматом пути к файлу (DOS/Windowsиспользуют в качестве разделителя "\"; Unix — "/"; а Acorn — ".").
И наконец, я полагаю, что сейчас надо сосредоточиться не на архитектуре процессора, а на архитектуре компьютера. Надо сделать так, чтобы в компьютере можно было поменять процессор или установить несколько разных процессоров. Короче, эту тему я сейчас как раз обдумываю.
А про софтовые решения можно бесконечно спорить, но маркетота все равно решает же.
Про «сейчас надо сосредоточиться не на архитектуре процессора, а на архитектуре компьютера», все так, но, например, была такая теплая ламповая связка — БеОС и основа в виде своего компа. :) Что случилось? Маркетота случилась, как обычно. %) И микрософты еще додавили.
Про «чтобы в компьютере можно было поменять процессор или установить несколько разных процессоров» — это ж чисто с Акорна калька. =)
На вирусы в то время всем было пофиг же. :)AidsTest твовал в 1988..1998 годах. Очевидно, что на момент его возникновения на вирусы было совершенно не пофиг.
А про софтовые решения можно бесконечно спорить, но маркетота все равно решает же.Никто с этим не спорит. Но у Acorn маркетинг был заведомо пораженческий — как будто они намеренно сливали рынок пиюкам и мелкомягким.
была такая теплая ламповая связка — БеОС и основа в виде своего компаА это тут при чём? BeOS проигрывала по той же схеме, что и все остальные — Novell NetWare, FreeBSD, Linux, OS/2 и все остальные операционки для писюка: рынок операционок сильнее всех остальных сконен к монополизации. А кто будет монополистом — предопределил контракт IBM с Биллом Гейтсом.
Успешно конкурировать можно было исключительно с собственной аппаратной платформой — при условии, что эта платформа хотя бы в каком-то сегменте будет лучше писюков по соотношению цены и производительности.
Про «чтобы в компьютере можно было поменять процессор или установить несколько разных процессоров» — это ж чисто с Акорна калька. =)Насколько я помню, Acorn'овские 8-битные компьютеры позволяли подключить к основному системному блоку дополнительный блок — «второй процессор» со своей памятью. Но такой процессор можно было подключить только один. Причём в силу большого расстояния — скорость передачи данных была довольно низкой (впрочем, для тогдашних частот в пределах до 10 MHz это было не актуально).
А вот к 32-битным Archimedes дополнительные процессоры не подключались.
Я же предполагаю установку внутрь компьютера большого числа процессоров. В современном системном блоке (в корпусе) имеется место для установки семи плат расширения с внешним выходом. Я предполагаю использовать стандартный корпус — т.е. те же семь плат с внешним выходом; и ещё примерно столько же внутренних плат без внешнего выхода.
А это тут при чём?Как эт при чем? Там был свой комп и остальное, то был НЕ РС! Изначально. Это уже потом они мигрировали на интел и там же и заглохли, мс задушила их.
Я же предполагаю установку внутрь компьютера большого числа процессоров. В современном системном блоке (в корпусе) имеется место для установки семи плат расширения с внешним выходом.Ну в целом сейчас все так есть — в каждой плате расширения есть свой проц. А то и не один. :)
Но я понял мысль, она не нова, просто я честно хз зачем такое обычному юзеру может понадобиться…
Прочитал про BeBox. Прикольно, я не знал.
Интересно, как они использовали память — UMA, NUMA, NonMA?
То, что в нынешних платах расширения есть свои процессоры — я в курсе. Я даже показывал студентам Etnernet-плату (для 8-битной ISA), на которой был процессор 80186 — иллюстрировал свои постулаты.
Но у меня идея существенно иная:
На сетевую плату или плату выносится драйвер сетевого чипа, драйвер IP (или иного протокола 3-го уровня OSI) и драйвер TCP+ICMP.
На плату дискового контроллера выносится драйвер SATA-чипа, драйвер RAID-массива и драйвер файловой системы (и вообще, RAID-массив интегрирован с файловой системой, ибо это выгодно).
Т.е. внутри операционки нет драйверов, а общение с платой расширения происходит по стандартному протоколу.
Зачем это нужно:
Это очевидно, если вспомнить, что для выполнения сетевой и дисковой частей не требуется FPU. Вот и не надо ставить его — получается сильная экономия на транзисторах и на энергопотреблении/тепловыделении. Заодно рассеивать тепло станет легче.
И главное — работа с отдельной памятью позволяет поставить много модулей памяти и резко понизить требования к кэш-памяти: можно будет снизить размер кэш-памяти и не надо будет синхронизировать кэши разных процессоров.
Про обычных юзеров я не знаю. Вообще, такая система будет хороша при запуске высоконагруженного Web-сервера со скриптами и с СУБД. А ещё лучше — при запуске большого количества вирт.машин, благо они "развязаны" (не взаимодействуют между собой).
Кроме того, я полагаю, что физическая изоляция программ (выполнение программ на разных процессорах с разной памятью) улучшит безопасность.
Если бы Вы сослались на какое-нибудь святое писание (что-то типа книги Вирта или Танненбаума), я бы понял Вошу мотивацию. Но Ваша ссылка ведён на текст, который явно не является святым каноном.
Ну да, моя идея противоречит концепции RDMA. А разве я подписывался блюсти эту концепцию?
Более того: в обычных кластерных системах RDMA невозможет. Ибо политика свопинга осуществляется каждой нодой кластера независимо, и чужая память, к которой адресуется RDMA-запрос, в этот момент м.б. выгружена на диск.
Хотя в предлагаемой мной системе как раз RDMA вполне реализуем — в одном из вариантов элементы системы (отдельные платы) способны предоставлять NUMA-доступ другим платам. Например, это может потребоваться в случае, если у одной из плат резко выросла потребность в памяти, а у другой платы есть свободная память — и эту свободную память предоставляют под свопинг.
Однако, в этой схеме прямой доступ к чужой памяти получают не приложения, а программы, работающие в kernel-space. И здесь нет речи об объединении всей памяти в единое пространство — чужая память всё-таки гораздо медленнее, чем своя (в смысле — медленнее выполняет запросы); и программы должны это учитывать.
Память, к которой направляется RDMA запрос регистрируется в сетевой карте RDMA через её драйвер (а иногда — еще и в IOMMU). Зарегистрированная память не может менять физ.адрес и/или свопиться, т.к. карта будет обращаться к ней по физадресу (транзакцией по шине PCIe).
http://www.rdmamojo.com/2012/09/07/ibv_reg_mr/ "Can I use memory block in RDMA without this registration? — Basically no."
https://blogs.cisco.com/performance/registered-memory-rma-rdma-and-mpi-implementations "registered memory is both a curse and a blessing.… Registering both pins the memory in the operating system (i.e., tells the OS “never swap this page out or move it”) and notifies the NIC of the virtual-to-physical address mapping of this memory."
http://www.people.vcu.edu/~xhe2/publications/Journals/JNCA-2009.pdf "it is required to register a memory region where the user buffers are located. In the process
of registration, the device driver first maps the virtual memory
address to the physical address, then pins the memory region to
make sure that in the operations of RDMA, the memory region is
not swapped out from physical memory. After mapping and
pinning, the driver reports the information of the memory region
to NIC, in which a table is used to keep information of all
registered memory regions"
Зарегистрированная память не может менять физ.адрес и/или свопиться, т.к. карта будет обращаться к ней по физадресу (транзакцией по шине PCIe).А как же тогда «64-битные смещения Tagged Offsets задают не физические, а логические (виртуальные) адреса, которые необходимо подвергнуть страничной трансляции»?
Ну, в принципе, идея годная. Но каким образом предполагается использовать эту схему?
Могут ли пользоваться этой схемой недоверенные программы, которые намеренно или по незнанию могут обрушить (или хотя бы за'DoS'ить) систему? Или доступ к этому сервису м.б. только у доверенных программ?
Про Tagged Offsets: "7.3 Memory Registration, 7.3.1 Memory Regions" и далее из RDMA Protocol Verbs Specification (Version 1.0) 2003 (draft-hilland-iwarp-verbs-v1.0) http://www.rdmaconsortium.org/home/draft-hilland-iwarp-verbs-v1.0-RDMAC.pdf#page=95
Base Tagged Offset (Base TO) — The offset assigned to the first byte of a Memory Region or a Memory Window.
Memory Translation and Protection Table(s) (TPT) — The data
structure(s) used by an RNIC to control buffer access and
translate STags and Tagged Offsets into local memory addresses
directly accessible by the local Node
Memory Registration provides the RNIC with a mapping between a STag and Tagged Offset and a Physical Memory Address
Before using a data buffer with the RI, all Consumers MUST
explicitly register with the RI the memory locations associated with
the data buffer
Memory Registration MAY fail due to the RNIC’s inability to find
resources to hold information needed by the RNIC to record the
registration.
Т.е. всю память нужно регистрировать, в сетевой карте есть таблицы регистрации/трансляции.
На шинах PCIe используются либо физ адреса, либо адреса, транслируемые в IOMMU. При регистрации MR драйвер (предварительно заблокировав регион от перемещений в физпамяти и откачки в swap — что-то вроде mlock — "ib_umem_get — Pin and DMA map userspace memory." ) пропишет в карте параметры региона и таблицу трансляции Tagged Offset — физстраницы (или страниц в iommu-адресации — sg_dma_address — get bus addresses of each of the SG entries). Удаленный узел сможет использовать Tagged Offsets, но карта сама будет транслировать их в адреса, используемые на шине. Это похоже на виртуальную память, но данная трансляция не обязана совпадать с трансляцией вирт. памяти, используемой приложением (да карта и не сможет найти и распарсить таблицы трансляции приложения).
На объем памяти с mlock в Linux есть ряд лимитов (ulimit, RLIMIT_MEMLOCK)
https://lwn.net/Articles/133649/ Supporting RDMA on Linux 2005
Drivers which need to make user-space memory available to their hardware will call get_user_pages(), which achieves two useful things: it pins the pages into physical memory, and generates an array of physical addresses for the driver to use.…
The resource accounting issues can be partially solved by requiring the process to lock the pages itself (using mlock()) before setting them up for RDMA; that will bring the normal kernel resource limits into play.
Администратор системы может изменить лимиты для пользователей, которым нужен RDMA: https://www.open-mpi.org/faq/?category=openfabrics#ib-locked-pages-user 14, "16. How can a system administrator (or user) change locked memory limits?"
Да, в линукс сообщали о каких-то проблемах при блокировании памяти из некоторых сетевых драйверов и учете количества памяти (лимитов): https://lwn.net/Articles/600502/ Locking and pinning 2014
So users can, for all practical purposes, lock pages in memory via actions like the creation of remote DMA (RDMA) buffers; those pages are not currently counted against the limit on locked pages. This irritates administrators and developers who want the limit on locked pages to apply to all locked pages, not just some of them.
https://www.openfabrics.org/images/eventpresos/2017presentations/203_LinuxKernel_CLameter.pdf#page=8
но фактически драйвера из подсистемы infiniband (самый популярный вариант RDMA, доступный на рынке) учитывает именно RLIMIT_MEMLOCK (и CAP_IPC_LOCK) http://elixir.free-electrons.com/linux/v4.11/source/drivers/infiniband/core/umem.c#L171
locked = npages + current->mm->pinned_vm;
lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) {
ret = -ENOMEM;
goto out;
}
недоверенные программы, которые намеренно или по незнанию могут обрушить (или хотя бы за'DoS'ить) систему? Или доступ к этому сервису м.б. только у доверенных программ?
Доступ к регистрации будет только у тех программ, которые имеют доступ к файлу RDMA устройства в /dev (вероятно, пользователь должен входить в группу "rdma" или подобную). Регистрация в драйвере будет доступна только на машинах, где установлена RDMA-карта и загружен её драйвер. Есть лимит по количеству памяти в карте и её драйвере; судя по OpenMPI FAQ лимит MEMLOCK учитывается (и настраивается администратором машины); ядро не позволит провести регистрацию всей физпамяти (есть резерв памяти для ядра). Да, если на машине запустить два rdma-приложения, которые хотят залочить по 90% памяти, памяти на всех не хватит и одно из них вероятно получит ошибку при регистрации — физпамять это общий ресурс.
Этому решению почти 20 лет, оно медленное, поскольку некэшируемое чтение занимает много процессорных тактов, а кэшировать его нельзя по очевидным причинам — вместо новых чисел будут считываться кэш-копии первого сгенерированного числа. Приведем аргумент из другой области: в рамках спецификации x2APIC для доступа к регистрам локального контроллера прерываний вместо привычного диапазона MMIO (Local APIC base = FEE00000h) сейчас применяется доступ посредством регистров MSR (Model-Specific Registers).
Вместе с тем, в будущем нас скорее всего ждет унификация — метод получения случайного числа может быть Implementation-Specific, а в качестве внешнего интерфейса используется драйвер, например EFI_RNG_PROTOCOL, инкапсулирующий метод доступа к устройству и позволяющий использовать различные методы, не нарушая совместимость (это день завтрашний). По крайней мере теоретически это так выглядит.
Завернуть запрос в I/O-порт (команду IN/OUT) обратно в процессор — не проблема. Благо контроллер шин адреса+данных давно уже в процессоре. И это будет не медленнее, чем отдельная команда.
Единственное преимущество специальной команды — это возможность использования этой команды в user-space.
BIOS — это программа. ROM — это микросхема, содержащая программу или данные (можно BIOS, можно что угодно другое — например, операционку с программами, Acorn подтверждает).
Фраза "генератор случайных чисел в составе микросхемы BIOS ROM" бессмысленна.
Унификация через драйвер — это стандартный путь решения задачи, когда один и тот же результат на разных платформах получают разными способами. Однако, этот способ — реально медленный; обычно лучше внедрять нужный код внутрь программы при компиляции.
Я зачем нужна совместимость, особенно "со всеми-всеми-всеми существующими архитектурами"? Кто сейчас нуждается в совместимости с Z80, Motorolla 68k и прочими "героями вчерашних дней"?
Есть масса ниш, куда можно вторгнуться, не заботясь о совместимости.
Например, LAMP: Linux + Apache + MySQL + PHP (в наше время компоненты м.б. другие, но аналогичные. Для новой архитектуры портируются Linux и Си-компилятор, после чего без труда портируются все программы. Рынок достаточно востребованный.
Другой рынок — это рынок хостинга вирт.машин. Тут надо портировать ещё и вирт.машину; но основная её часть переносится простой перекомпиляцией. Скорее всего, появится ограничение на список поддерживаемых операционок — ну так для успешного старта достаточно поддерживать хотя бы одну распространённую, Linux годится.
Третий рынок — это рынок платёжных терминалов. Тут совместимость вообще вредна, ибо она — совместимость с вирусами и прочими вредоносными программами.
И было даже лучше — Transmeta.
Не взлетело.
Почему у меня такое чувство, что автор не имеет представления о чем пишет?
Не увиделось ничего "изнутри", статья не более чем плохой перевод документации по новым инструкциям ryzen, даже без попыток вникнуть в детали :(
Обращайтесь с конкретными вопросами. Помогу понять чем отличаются все эти разные XSAVE* инструкции, CLFLUSH от CLFLUSHOPT и что-такое write-back/write-allocate и какое отношение они имеют к temporal/non-temporal.
CLZERO как инструкция давненько напрашивается. Вы будете удивлены как часто бывает нужно проинициализировать (читай: обнулить) какой-нибуль кусочек памяти. Например при создании нового объекта в ЯВУ.
Вопрос в том какие есть альтернативные пути это сделать:
- Можно обнулять с помощью streaming stores. но не самый лучший вариант если объект не большой и сразу будет использоваться. После обнуления streaming stores в кешах процессора ничего не останется и первое использование будет дорого стоит (cache miss до самой памяти)
- Можно использовать rep stosb.
- На Intel с поддержкой AVX-512 можно тупо сделать 512-битный store, хоть WB streaming, хоть обычный.
Intel решил не добавлять новую инструкцию потому что добился того, что альтернативные пути работают не хуже, а значит она просто не нужна.
AMD не смог или не захотел докрутить rep stosb и предпочел создать новую инструкцию.
На первый взгляд она кажется нишевой (только на AMD, Intel ее не поддердивает и не собирается), но это только на первый взгляд. Run time library (тот же libc) у большинства ЯВУ уже сейчас платформенно зависимы, умеют делать CPUID и выбирать лучшую имплементацию для каждой конкретной платформы. Так что CLZERO будет использоваться или уж используется везде и всюду, каждый раз когда ваша старая программа вызывает тот же memset, malloc, calloc и т.п. Ну а на Intel они будет использовать rep stosb и оно будет не сколько не медленнее и с теми же "фичами", только за кулисами.
CLZERO это макрос для контроллера памяти и далее контроллер уже сам выполняет запись нулей? Или протокол DRAM имеет возможность передать только адрес, без пакета нулей, и тем самым экономится bandwidth?
Если на Intel выполнять rep stosb, но с ненулевым заполнителем, оптимизация пропадает?
Если строка перезаписана полностью (записано 64 байта по адресу кратному 64), то исходное содержимое ОЗУ можно проигнорировать, так как оно полностью «перекрыто» новыми данными и содержимое кэш-строки является функцией только данных записи и не является функцией исходного содержимого ОЗУ.
Такой метод обслуживания записи без обращения к ОЗУ, экономит не только такты, но и потребляемую мощность. Да, верно подмечено, у процессоров Intel, поддерживающих AVX512, инициировать 64-байтную запись можно и без CLZERO инструкцией записи, например, VMOVAPD [rax],zmm0. Такой подход работает для 64-байтных кэш-строк (512 бит = 64 байта), но пока нет оснований полагать, что размер кэш-строк изменится в новых процессорах. Или есть?
Кстати, гораздо интереснее не CLZERO а вообще пропущенные в статье MONITORX/MWAITX. Вот это больше похоже на настоящий прорыв. Оригинальные MONITOR/MWAIT доступны только для OS (ring0) и не поддерживают выход по timeout. В результат у user-code нет альтернативы кроме использования busy (pause) loops. На Ryzen c MONITORX/MWAITX можно практически вырубить энергопортребление или отдать все ресурсы другому потоку вместо тупого pause loop который еще и в память будет каждую итерацию заново лазить семафор проверять!
А вот хорошая иллюстрация из независимого источника:
Захотелось что-нибудь поделать на ассемблере
Есть еще люди, которым интересно докопаться до. Сей факт радует больше самой статьи.
Неплохо бы чтоб к сему чуду на «AMD Develiper Hub» еще и BKDG своевременно появлялось.
Мелочь, но с ней приятней.
Верьте делам, а не словам.
Если сгенерирован Page Fault (PF, vector 0Eh), значит исследуемая последовательность байтов является инструкцией, при этом ее часть «залезла» на вторую страницу, что позволяет сделать вывод о длине байтового представления инструкции.
Если вместо Page Fault генерируется General Protection Fault (GPF, vector 0Dh) или Invalid Opcode Exception (vector 06h), то это значит, что байтов, расположенных в первой странице, процессору достаточно, чтобы «понять» что операция недопустима, «понять» до попытки адресации второй страницы.
Когда-то делали что-то подобное под DOS для поиска недокументированных MSR. Но там все было значительно проще:
- Устанавливаем собственную процедуру обработки GPF (vector 0Dh)
- Загружаем в ECX адрес исследуемого (якобы несуществующего) MSR
- Выполняем инструкцию RDMSR
- Если не генерируется General Protection Fault, значит этот MSR существует.
Делая тот же трюк с недокументированными кодами инструкций нет уверенности в том, что на любой недопустимый код операции процессор дисциплинированно сгенерирует #UD (vector 06h) или #GPF (vector 0Dh), в ходе исследования возможны зависания и рестарты, вероятность которых можно уменьшить, проводя исследования на виртуальной машине, что автор и сделал.
AMD Ryzen: взгляд изнутри