Поскольку 32-разрядная система не может управлять числом 2 ^ 33 (из-за очевидного 32-разрядного ограничения), как можно управлять 80-разрядным числом с плавающей запятой ?
Это должно требовать "80-бит" ...
Поскольку 32-разрядная система не может управлять числом 2 ^ 33 (из-за очевидного 32-разрядного ограничения), как можно управлять 80-разрядным числом с плавающей запятой ?
Это должно требовать "80-бит" ...
Ответы:
Одно из значений 32-битного процессора состоит в том, что его регистры имеют ширину 32 бита. Это не означает, что он не может иметь дело, скажем, с 64-битными числами, просто он должен иметь дело с младшей 32-битной половиной сначала, а затем с верхней 32-битной половиной секунды. (Вот почему ЦП имеют флаг переноса .) Это медленнее, чем если бы ЦП мог просто загружать значения в более широкий 64-битный регистр, но все же возможно.
Таким образом, «разрядность» системы не обязательно ограничивает размер чисел, с которыми может работать программа, потому что вы всегда можете разбить операции, которые не вписываются в регистры ЦП, на несколько операций. Таким образом, он замедляет операции, потребляет больше памяти (если вам нужно использовать память как «блокнот») и усложняет программирование, но операции все еще возможны.
Однако ничего подобного не имеет значения, например, с 32-разрядными процессорами Intel и процессорами с плавающей запятой, поскольку часть процессора с плавающей запятой имеет свои собственные регистры, а их ширина составляет 80 бит. (В начале истории x86, возможность с плавающей запятой была отдельным чипом, она была интегрирована в CPU начиная с 80486DX.)
Ответ @ Breakthrough вдохновил меня добавить это.
Значения с плавающей запятой, поскольку они хранятся в регистрах FPU, работают совсем не так, как двоичные целочисленные значения.
80 битов значения с плавающей запятой делятся между мантиссой и показателем степени (в числах с плавающей запятой также есть «основание», которое всегда равно 2). Мантисса содержит значащие цифры, а показатель степени определяет, насколько велики эти значащие цифры. Таким образом, нет никакого «переполнения» в другом регистре, если ваше число становится слишком большим, чтобы поместиться в мантиссе, ваш показатель возрастает, и вы теряете точность - то есть, если вы преобразуете его в целое число, вы потеряете десятичные разряды справа - Вот почему это называется плавающей точкой.
Если ваш показатель степени слишком велик, у вас возникает переполнение с плавающей точкой, но вы не можете легко распространить его на другой регистр, поскольку показатель степени и мантисса связаны друг с другом.
Я мог бы быть неточным и ошибочным в отношении некоторых из них, но я верю, что это суть этого. (Эта статья в Википедии иллюстрирует вышесказанное более кратко.)
Ничего страшного, что это работает совершенно по-другому, поскольку вся часть процессора с плавающей точкой находится в своем собственном мире - вы используете специальные инструкции процессора для доступа к нему и тому подобное. Кроме того, что касается вопроса, поскольку он разделен, разрядность FPU не тесно связана с разрядностью собственного процессора.
источник
-fomit-frame-pointer
чтобы вернуть этот регистр.Все 32-разрядные, 64-разрядные и 128-разрядные обозначают длину слова процессора, которую можно рассматривать как «основной тип данных». Часто это количество битов, передаваемых в / из ОЗУ системы, и ширина указателей (хотя ничто не мешает вам использовать программное обеспечение для доступа к большему объему ОЗУ, чем тот, к которому может обращаться один указатель).
Предполагая постоянную тактовую частоту (а также то, что все остальное в архитектуре является постоянной) и предполагая, что чтение / запись в память имеют одинаковую скорость (мы предполагаем, что здесь 1 тактовый цикл, но это далеко не так в реальной жизни), вы можете добавьте два 64-разрядных числа за один такт на 64-разрядном компьютере (три, если считать число из оперативной памяти):
Мы также можем сделать то же самое вычисление на 32-битной машине ... Однако на 32-битной машине мы должны сделать это программно, так как младшие 32-битные должны быть сначала добавлены, компенсировать переполнение, затем добавить старшие 64-битные:
Проанализировав мой синтаксис готовой сборки, вы можете легко увидеть, как операции с более высокой точностью могут занимать экспоненциально более длительное время на компьютере с меньшей длиной слова. Это реальный ключ для 64-битных и 128-битных процессоров: они позволяют нам обрабатывать большее количество битов за одну операцию. Некоторые машины содержат инструкции для добавления других величин с переносом (например,
ADC
на x86), но в приведенном выше примере учитываются произвольные значения точности.Теперь, чтобы расширить это до вопроса, просто посмотреть, как мы можем добавить числа больше, чем имеющиеся у нас регистры - мы просто разбиваем проблему на куски размером с регистры и работаем оттуда. Хотя, как упомянул @MatteoItalia , стек FPU x87 имеет встроенную поддержку 80-битных величин, в системах, где такая поддержка отсутствует (или процессоры не имеют блока с плавающей запятой полностью!), Эквивалентные вычисления / операции должны выполняться в программном обеспечении .
Таким образом, для 80-битного числа после добавления каждого 32-битного сегмента также будет проверяться переполнение в 81-м бите и, при необходимости, обнулять биты более высокого порядка. Эти проверки / нули выполняются автоматически для определенных команд x86 и x86-64, где указываются размеры операнда источника и назначения (хотя они указываются только в степени 2, начиная с ширины в 1 байт).
Конечно, с числами с плавающей запятой нельзя просто выполнить двоичное сложение, поскольку мантисса и значащие цифры упакованы вместе в форме смещения. В ALU на процессоре x86 есть аппаратная схема, чтобы выполнить это для 32-разрядных и 64-разрядных операций с плавающей запятой IEEE; однако даже в отсутствие модуля с плавающей запятой (FPU) те же вычисления могут выполняться в программном обеспечении (например, с использованием научной библиотеки GNU , которая использует FPU при компиляции на архитектурах с отступлением от программных алгоритмов). если не доступно аппаратное обеспечение с плавающей запятой [например, для встроенных микроконтроллеров без FPU]).
При наличии достаточного количества памяти можно также выполнять вычисления на числах произвольной (или «бесконечной» - в пределах реалистичных границ) точности, используя больше памяти, поскольку требуется большая точность. Одна из реализаций этого существует в библиотеке GNU Multiple Precision , обеспечивающей неограниченную точность (конечно, до тех пор, пока ваша память не заполнится) для целочисленных, рациональных операций и операций с плавающей запятой.
источник
Архитектура памяти системы может позволять вам перемещать только 32 бита одновременно, но это не мешает использовать большие числа.
Подумайте о умножении. Вы можете знать свои таблицы умножения до 10x10, но у вас, вероятно, нет проблем с выполнением 123x321 на листе бумаги: вы просто разбиваете его на множество мелких проблем, умножаете отдельные цифры, заботитесь о переносе и т. Д.
Процессоры могут делать то же самое. В «старые времена» у вас было 8 битных процессоров, которые могли выполнять математику с плавающей запятой. Но они были оооочень.
источник
«32-разрядный» - это действительно способ категоризации процессоров, а не стандартное решение. 32-битный процессор обычно имеет 32-битные регистры общего назначения для работы.
Тем не менее, нет четкого требования, чтобы все в процессоре было выполнено в 32-битном режиме. Например, для «32-разрядного» компьютера не было ничего необычного в том, чтобы иметь 28-разрядную адресную шину, потому что аппаратное обеспечение было дешевле. По той же причине 64-разрядные компьютеры часто имеют только 40-разрядную или 48-разрядную шину памяти.
Арифметика с плавающей точкой - другое место, где размеры меняются. Многие 32-разрядные процессоры поддерживают 64-разрядные числа с плавающей запятой. Они сделали это, сохранив значения с плавающей запятой в специальных регистрах, которые были шире, чем регистры общего назначения. Чтобы сохранить одно из этих больших чисел с плавающей запятой в специальных регистрах, нужно сначала разбить число на два регистра общего назначения, а затем выполнить инструкцию, чтобы объединить их в число с плавающей точкой в специальных регистрах. Оказавшись в этих регистрах с плавающей запятой, значения будут обрабатываться как 64-разрядные числа с плавающей запятой, а не как пара 32-разрядных половин.
Упоминаемая вами 80-битная арифметика является частным случаем этого. Если вы работали с числами с плавающей запятой, вы знакомы с неточностью, которая возникает из-за проблем округления с плавающей запятой. Одно из решений для округления состоит в том, чтобы иметь больше битов точности, но тогда вам нужно хранить большие числа и заставлять разработчиков использовать необычно большие значения с плавающей запятой в памяти.
Решение Intel состоит в том, что все регистры с плавающей запятой являются 80-битными, но инструкции по перемещению значений в / из этих регистров в основном работают с 64-битными числами. Пока вы работаете полностью в стеке с плавающей запятой Intel x87, все ваши операции выполняются с точностью до 80 бит. Если вашему коду необходимо извлечь одно из этих значений из регистров с плавающей запятой и сохранить его где-то, он усекает его до 64-битных значений.
Мораль истории: такие категории, как «32-разрядные», всегда опаснее, когда вы углубляетесь в вещи!
источник
«32-битный» процессор - это тот, в котором большинство регистров данных являются 32-битными регистрами, и большинство инструкций работают с данными в этих 32-битных регистрах. 32-разрядный ЦП также может одновременно передавать данные в 32-разрядную память и из нее. Большинство 32-битных регистров не означает, что все регистры 32-битные. Короткий ответ заключается в том, что 32-разрядный ЦП может иметь некоторые функции, использующие другие битовые счета, такие как 80-разрядные регистры с плавающей запятой и соответствующие инструкции.
Как сказал @spudone в комментарии к ответу @ ultrasawblade, первым процессором x86, который интегрировал операции с плавающей запятой, был Intel i486 (в частности, 80486DX, но не 80486SX), который, согласно странице 15-1 программистов микропроцессоров i486 Справочное руководство включает в свои числовые регистры «Восемь индивидуально адресуемых 80-разрядных числовых регистров». I486 имеет 32-битную шину памяти, поэтому для передачи 80-битного значения потребуется 3 операции с памятью.
Предшественник поколения 486, i386, не имел встроенных операций с плавающей запятой. Вместо этого у него была поддержка использования внешнего «сопроцессора» с плавающей запятой, 80387. Этот сопроцессор имел почти те же функциональные возможности, которые были интегрированы в i486, как вы можете видеть на странице 2-1 Справочного руководства программиста 80387 .
80-битный формат с плавающей запятой, кажется, возник с 8087, математическим сопроцессором для 8086 и 8088. 8086 и 8088 были 16-битными ЦП (с 16-битной и 8-битной шинами памяти), и все еще были в состоянии использовать 80-битный формат с плавающей запятой, используя преимущества 80-битных регистров в сопроцессоре.
источник