Экзотические архитектуры, о которых заботятся комитеты по стандартам
Я знаю, что стандарты C и С++ оставляют много аспектов реализации языка только потому, что, если есть архитектура с другими характеристиками, было бы очень сложно или невозможно написать для нее стандартный соответствующий компилятор.
Я знаю, что 40 лет назад у любого компьютера была своя уникальная спецификация. Однако я не знаю ни одной архитектуры, используемой сегодня, где:
-
CHAR_BIT != 8
-
signed
не является двумя дополнениями (я слышал, что у Java были проблемы с этим).
- Плавающая точка не соответствует IEEE 754 (Edit: Я имел в виду "не в двоичном кодировании IEEE 754" ).
Причина, по которой я спрашиваю, заключается в том, что я часто объясняю людям, что хорошо, что С++ не предоставляет никаких других низкоуровневых аспектов, таких как типы фиксированного размера †. Это хорошо, потому что, в отличие от "других языков", он делает ваш код переносимым при правильном использовании (Edit: потому что его можно портировать на большее количество архитектур без необходимости эмуляции низкоуровневых аспектов машины, например, например, арифметики с двумя дополнениями на архитектуре знака +, Но мне плохо, что я не могу указать на какую-либо конкретную архитектуру.
Итак, вопрос в том, какие архитектуры демонстрируют вышеуказанные свойства?
† uint*_t
являются необязательными.
Ответы
Ответ 1
Взгляните на этот
Серверы Unisys ClearPath Dorado
предлагая обратную совместимость для людей, которые еще не перенесли все их программное обеспечение Univac.
Ключевые моменты:
- 36-битные слова
-
CHAR_BIT == 9
- одно дополнение
- 72-битная плавающая точка без IEEE
- отдельное адресное пространство для кода и данных
- слово-имя
- нет выделенного указателя стека
Не знаю, предлагают ли они C++ компилятор, хотя могли.
И теперь появилась ссылка на недавнее издание своего руководства по C:
Справочное руководство по программированию компилятора Unisys C
В разделе 4.5 приведена таблица типов данных с 9, 18, 36 и 72 битами.
Ответ 2
Ни одно из ваших предположений не подходит для мэйнфреймов. Для начала я не знаю
мейнфрейма, использующего IEEE 754: IBM использует базовую 16 с плавающей запятой и
оба из мейнфреймов Unisys используют базу 8. Машины Unisys немного
особенно во многих других отношениях: Бо упомянул архитектуру 2200,
но архитектура MPS еще более странная: 48-битные тегированные слова.
(Является ли слово указателем или нет, зависит от бит в слове.)
И числовые представления сконструированы так, что нет реальных
различие между плавающей точкой и интегральной арифметикой: плавающее
точка - основание 8; он не требует нормализации, и в отличие от всех
другая плавающая точка, которую я видел, она ставит десятичную строку справа от
мантисса, а не слева, и использует знаковое значение для
экспонента (в дополнение к мантиссе). С учетом того, что
интегральное значение с плавающей запятой имеет (или может иметь) точно такой же бит
представление как знаковое целое число. И нет плавающего
точечные арифметические инструкции: если показатели двух значений
оба 0, инструкция выполняет интегральную арифметику, в противном случае
арифметика с плавающей запятой. (Продолжение философии маркировки в
архитектура.) Это означает, что хотя int
может занимать 48 бит, 8
из них должно быть 0 или значение не будет рассматриваться как целое число.
Ответ 3
Полное соответствие IEEE 754 редка в реализациях с плавающей точкой. И ослабление спецификации в этом отношении допускает множество оптимизаций.
Например, поддержка поднабора отличается от x87 и SSE.
Оптимизации, такие как слияние умножения и сложения, которые были разделены в исходном коде, слегка меняют результаты, но это хорошая оптимизация на некоторых архитектурах.
Или при строгом соблюдении правил IEEE для x86 может потребоваться установка определенных флагов или дополнительных передач между регистрами с плавающей запятой и нормальной памятью, чтобы заставить его использовать указанный тип с плавающей запятой вместо своих внутренних 80-битных поплавков.
И на некоторых платформах нет аппаратных всплывающих окон вообще и, следовательно, нужно имитировать их в программном обеспечении. И некоторые из требований IEEE 754 могут быть дорогими для реализации в программном обеспечении. В частности, могут быть проблемы с правилами округления.
Мое заключение состоит в том, что вам не нужны экзотические архитектуры, чтобы попасть в ситуации, если бы вы не всегда хотели гарантировать строгое соблюдение IEEE. По этой причине несколько языков программирования гарантировали строгое соответствие IEEE.
Ответ 4
Я нашел эту ссылку, в которой перечислены некоторые системы, где CHAR_BIT != 8
. Они включают
некоторые DSP DSP имеют CHAR_BIT == 16
Чип BlueCore-5 (Bluetooth чип от Cambridge Silicon Radio), который имеет CHAR_BIT ==
16
.
И, конечно, есть вопрос о переполнении стека: На каких платформах есть что-то отличное от 8-битного char
Что касается систем с не-двумя дополнениями, то интересно прочитать comp.lang.С++. Модератор. Обобщены: есть платформы, имеющие свое дополнение или знак и представление величины.
Ответ 5
Я уверен, что VAX-системы все еще используются. Они не поддерживают плавающую точку IEEE; они используют свои собственные форматы. Alpha поддерживает как форматы с плавающей запятой VAX, так и IEEE.
У векторных машин Cray, таких как T90, также есть собственный формат с плавающей запятой, хотя новые системы Cray используют IEEE. (T90, который я использовал, был выведен из эксплуатации несколько лет назад, я не знаю, все ли находятся в активном использовании.)
T90 также имел/имеет некоторые интересные представления для указателей и целых чисел. Нативный адрес может указывать только на 64-битное слово. У компиляторов C и С++ был CHAR_BIT == 8 (необходимо, потому что он запускал Unicos, это был стиль Unix, и он должен был взаимодействовать с другими системами), но собственный адрес мог указывать только на 64-битное слово. Все операции на байтовом уровне были синтезированы компилятором, а void*
или char*
хранили смещение байта в 3-х разрядах слова высокого порядка. И я думаю, что у некоторых целых типов были биты заполнения.
Другими примерами являются мэйнфреймы IBM.
С другой стороны, эти конкретные системы необязательно должны исключать изменения в языковом стандарте. Cray не проявлял особого интереса к обновлению своего компилятора C до C99; предположительно, то же самое, что и для компилятора С++. Возможно, было бы разумно ужесточить требования к размещенным реализациям, например, требовать CHAR_BIT == 8, IEEE формат с плавающей запятой, если не полную семантику, и 2'-дополнение без дополняющих битов для целых чисел со знаком. Старые системы могут продолжать поддерживать более ранние языковые стандарты (C90 не умер, когда вышел C99), и требования могут быть более свободными для автономных реализаций (встроенных систем), таких как DSP.
С другой стороны, могут быть веские причины для будущих систем делать вещи, которые сегодня считаются экзотическими.
Ответ 6
CHAR_BITS
В соответствии с исходным кодом gcc:
CHAR_BIT
- это бит 16
для архитектуры 1750a, dsp16xx.
CHAR_BIT
- бит 24
для архитектуры dsp56k.
CHAR_BIT
бит 32
для архитектуры c4x.
Вы можете легко найти больше:
find $GCC_SOURCE_TREE -type f | xargs grep "#define CHAR_TYPE_SIZE"
или
find $GCC_SOURCE_TREE -type f | xargs grep "#define BITS_PER_UNIT"
если CHAR_TYPE_SIZE
определено соответствующим образом.
Соответствие IEEE 754
Если целевая архитектура не поддерживает инструкции с плавающей запятой, gcc может генерировать резервное копирование программного обеспечения, которое по умолчанию не соответствует стандарту. Более того, можно использовать специальные опции (например, -funsafe-math-optimizations
, также отключает сохранение знака для нулей).
Ответ 7
Бинарное представление IEEE 754 было редко встречается на графических процессорах до недавнего времени, см. " Планетарная паранойя" с графическим процессором.
EDIT: в комментариях был поднят вопрос о том, относится ли плавающая точка GPU к обычным компьютерным программам, не связанным с графикой. Да, черт возьми! Большинство высокопроизводительных устройств, которые сегодня вычисляются в промышленности, производятся на графических процессорах; список включает в себя ИИ, интеллектуальный анализ данных, нейронные сети, физическое моделирование, прогноз погоды и многое другое. Одна из ссылок в комментариях показывает, почему: преимущество плавающих запятых по сравнению с графическими процессорами.
Еще одна вещь, которую я хотел бы добавить, что более актуально для вопроса OP: что люди делали 10-15 лет назад, когда плавающая точка с графическим процессором не была IEEE, и когда API не был таким, как сегодня OpenCL или CUDA для программирования графических процессоров? Верьте или нет, ранние пионеры-разработчики графических процессоров смогли запрограммировать GPU без API для этого! Я встретил одного из них в моей компании. Вот что он сделал: он закодировал данные, которые ему нужны, чтобы вычислить как изображение с пикселями, представляющими значения, над которыми он работал, а затем использовал OpenGL для выполнения необходимых ему операций (например, "гауссовское размытие") для представления свертки с нормальным распределением, и т.д.) и декодировал результирующее изображение обратно в массив результатов. И это все же было быстрее, чем использование процессора!
Подобным же образом NVidia наконец-то совместила свои внутренние двоичные данные с IEEE и представила API, ориентированный на вычисления, а не на манипуляции с изображениями.