LINUX.ORG.RU
ФорумTalks

как в процессорах чаще всего реализована команда деления?


1

1

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

★★★
Ответ на: комментарий от drBatty

Это проще, и намного дешевле аппаратного делителя.

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

i-rinat ★★★★★
()
Ответ на: комментарий от drBatty

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

mm3 ★★★
() автор топика
Ответ на: комментарий от i-rinat

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

как же ты достал доказывать сладость зелёного тем, что оно тяжёлое, опровергая мои слова о том, что вода мокрая…

операция аппаратная тогда, и только тогда, когда в процессоре есть её поддержка на уровне железа. В Pentium аппаратное сложение и умножение, ибо есть аппаратный сумматор и аппаратный умножитель. А то, что сложение разбивается на два этапа конвейера в младших пнях — не баг, а фича. Сумматоры хоть и половинные, за то работают на удвоенной частоте, и их две штуки. Потому за такт они могут два числа сразу сложить полного размера. Или 4 штуки, учитывая, что там два ALU. Или 8 штук, если они половинного размера. Если ты не знал, то распараллеливание сложения невозможно в принципе, ибо старший бит зависит от всех остальных, и его значение можно получить лишь ПОСЛЕ вычисления остальных. За то операция сложения конвейерезируется, т.е. можно одновременно обрабатывать два числа сразу одновременно складывая младшие половинки одного числа и старшие половинки другого. В таком сумматоре примерно столько же эл-тов как в полноразмерном, но он гибче и удобнее, ибо далеко не всегда нужно складывать полноразмерные числа. _Очень_ часто достаточно складывать лишь младшую часть, а старшая не изменяется, или изменяется с вероятностью 1/65536.

Аппаратный умножитель, AFAIK, был ещё с i8086го, и это никак не меняет тот факт, что умножение занимало далеко не один такт, а намного больше. Умножение тоже НЕ распараллеливается, хотя тоже отлично конвеерезируется.

А вот аппаратного делителя не было в i8086, если не считать аппаратной поддержки сложения(для деления нужно складывать числа, и если их уметь складывать по много сразу, то и делить можно получая много бит за один такт).

Как оно сейчас — я не знаю, однако уверен, что в intel так и занимаются сложением/умножением, и уверенно забили на деление, которое нужно очень редко IRL.

drBatty ★★
()
Ответ на: комментарий от i-rinat

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

А теперь посчитай в тактах.

в тактах уже считал: сам подумай, что выгоднее: иметь n конвейеров из n ступеней, в которых ВСЕ n×n элементов задействованы, или иметь n×n элементов, из которых работает лишь ОДИН? Ответ очевиден.

ну вот ещё один пример: для деления двух чисел 0..65535 тебе понадобится 32 матрицы 65536×65536 (по 512Mb каждая, всего 4Гб). Куда как проще создать конвейер из 16х сумматоров на 16 бит каждый (всего 256 однобитных сумматоров), которые За ОДИН такт и будут делить два 16и битных числа с остатком. Матрица таких сумматоров может не только умножать два числа за такт, но складывать по 16 чисел за такт.

drBatty ★★
()
Ответ на: комментарий от mm3

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

удалось. В 70х годах прошлого века. Для деления M битных целых чисел надо выполнить M последовательных сложений. За один такт это конечно невозможно, за то можно выполнить _одновременно_ M сложений РАЗНЫХ чисел. Т.е. сумматор №0 считает бит №0 текущего числа, а сумматор №1 считает бит №1 _предыдущего_ числа.

Другое дело, что эти деления нафиг никому не упёрлись. Они как бонус сейчас получаются.

ЗЫЖ да, в калькуляторах обычно деления вообще не было. Была функция 1/x. Часто она даже на отдельную кнопку выводилась. А считалась она путём интерполяции и экстраполяции многочлена n'ной степени, с заранее вычисленными коэффициентами. Как и квадратный корень. И да, умножителя тоже не было, был только однобитный сумматор.

drBatty ★★
()
Ответ на: комментарий от drBatty

как же ты достал доказывать сладость зелёного тем, что оно тяжёлое, опровергая мои слова о том, что вода мокрая…

Ты сейчас о себе говоришь.

операция аппаратная тогда

Когда сложность операции скрыта от пользователя (в данном случае — программиста). Есть инструкция деления — аппаратная, нет инструкции — нужно писать программу. Почему-то все кроме тебя придерживаются именно этой терминологии. А ты как всегда альтернативной.

i-rinat ★★★★★
()
Ответ на: комментарий от drBatty

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

А теперь посчитай в тактах.

в тактах уже считал: сам подумай, что выгоднее: иметь n конвейеров из n ступеней, в которых ВСЕ n×n элементов задействованы, или иметь n×n элементов, из которых работает лишь ОДИН? Ответ очевиден.

Ну вот опять эталонная шизофазия. Для 8086 доступны таблицы с числом тактов на инструкцию. А вместо того, чтобы посчитать, ты несёшь какой-то бред. Ну так и быть, я посчитаю за тебя: чтение из памяти занимает 4 такта. Логические операции, сдвиги и просто mov'ы занимают минимум 4 такта каждое. Итого — чтение из памяти (на 8086) в разы быстрее. Да и на 8088 оно в разы быстрее.

ну вот ещё один пример: для деления двух чисел 0..65535 тебе понадобится 32 матрицы 65536×65536 (по 512Mb каждая, всего 4Гб). Куда как проще создать конвейер из 16х сумматоров на 16 бит каждый (всего 256 однобитных сумматоров), которые За ОДИН такт и будут делить два 16и битных числа с остатком. Матрица таких сумматоров может не только умножать два числа за такт, но складывать по 16 чисел за такт.

О чём ты? Речь шла исключительно об умножении на константу на 8086. Что это за поток сознания?!

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Есть инструкция деления — аппаратная, нет инструкции — нужно писать программу.

на самом деле, это твоё изречение истинно только формально. На самом деле, программ для деления уже давно никто не пишет, они уже давно написаны. Программист просто пишет x/y, а уж как это будет вычисляться, он не только не знает, но и знать не желает.

Если тебе интересно, то в большинстве процессоров x/y будет выполняться софтово, и от того, что код находится внутри CPU, лично для тебя ничего не меняется. 40 лет назад он находился снаружи, но это ничего не меняло для прикладного программиста. Сейчас его (код) удалось засунуть внутрь якобы CISC, но это исключительно видимость. В RISC оно ессно так до сих пор снаружи и болтается.

Почему-то все кроме тебя придерживаются именно этой терминологии. А ты как всегда альтернативной.

я придерживаюсь истинного положения вещей, а видимость и иллюзии меня мало волнуют. IDIV из x86 — иллюзия. Хотя твоё право в неё верить я у тебя не отбираю. Верь, я разрешаю.

drBatty ★★
()
Ответ на: комментарий от i-rinat

Ну вот опять эталонная шизофазия. Для 8086 доступны таблицы с числом тактов на инструкцию. А вместо того, чтобы посчитать, ты несёшь какой-то бред. Ну так и быть, я посчитаю за тебя: чтение из памяти занимает 4 такта. Логические операции, сдвиги и просто mov'ы занимают минимум 4 такта каждое. Итого — чтение из памяти (на 8086) в разы быстрее. Да и на 8088 оно в разы быстрее.

это не у меня шизофазия, а у тебя эталонная безграмотность: 4 такта это МИНИМАЛЬНОЕ время, которое возникает только в случае идеально-сферической памяти, время доступа к которой ВСЕГДА равно нулю. У реальной памяти так, к сожалению, не бывает. Латентность есть всегда, но её нет в твоих таблицах.

И да, для деления 16и битных чисел нужно 4Гб памяти с нулевой латентностью. Да даже и не с нулевой — покажи мне 16и битный компьютер с 4Гб памяти? Жду с нетерпением (кстати, 8086 мог максимум 1048576 байт адресовать, если ты забыл).

ну вот ещё один пример: для деления двух чисел 0..65535 тебе понадобится 32 матрицы 65536×65536 (по 512Mb каждая, всего 4Гб). Куда как проще создать конвейер из 16х сумматоров на 16 бит каждый (всего 256 однобитных сумматоров), которые За ОДИН такт и будут делить два 16и битных числа с остатком. Матрица таких сумматоров может не только умножать два числа за такт, но складывать по 16 чисел за такт.

О чём ты? Речь шла исключительно об умножении на константу на 8086. Что это за поток сознания?!

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

drBatty ★★
()
Ответ на: комментарий от drBatty

У реальной памяти так, к сожалению, не бывает

Опять-таки, ты просто не знаешь, о чём говоришь. Во времена 8086 зазор между скоростями CPU и латентностью памяти не был таким большим, как сейчас.

это не у меня шизофазия

Да ну?

И да, для деления

Какого деления?

а зачем ты приплёл к вопросу о делении какое-то умножение, да ещё и на константу

А теперь проследи нить разговора. Знаешь, такие ссылочки, указывающие на предыдущий комментарий в нити. Прочитай мой первый комментарий в текущей нити.

Ты приплёл другую тему.

i-rinat ★★★★★
()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от i-rinat

Опять-таки, ты просто не знаешь, о чём говоришь. Во времена 8086 зазор между скоростями CPU и латентностью памяти не был таким большим, как сейчас.

это ты не знаешь, о чём говоришь: во времена 8086 не было огромных кешей на кристалле, и латентность играла огромную роль. Сейчас она важна только в некоторых приложениях, в частности таких, как ты предлагаешь — рандомно читать одно слово из 4х гигабайт. Ну а в те времена, проблема была даже с маленькими табличками. В отличие от памяти, в ALU никакой латентности не было, и вычисления завершались точно в срок, что намного важнее НЁХ, которую даёт RAM в виде латентности.

Какого деления?

ты сабж читаешь?

А теперь проследи нить разговора. Знаешь, такие ссылочки, указывающие на предыдущий комментарий в нити. Прочитай мой первый комментарий в текущей нити. Ты приплёл другую тему.

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

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

По всем этим причинам, табличные вычисления применялись и применяются только в _очень_ специальных случаях (вроде графики в ZX, но вы видели ЭТУ «графику»??).

drBatty ★★
()
Ответ на: комментарий от andreyu

таблицу синусов на speccy, было выгоднее расчитать предварительно

Да ладно там спекки, он родом из 70х, так и Вольф3Д образца 1992го этим не брезговал.

redgremlin ★★★★★
()
Ответ на: комментарий от drBatty

это ты не знаешь, о чём говоришь: во времена 8086 не было огромных кешей на кристалле

Потому что не было необходимости в кеше.

в частности таких, как ты предлагаешь — рандомно читать одно слово из 4х гигабайт

Не приписывай мне то, чего я не говорил.

ты сабж читаешь?

Читаю. Внимательно. Но как ты не заметил, отвечал я на конкретное сообщение, а не на оригинальное.

это ты приплёл другую тему

То есть ты так и не проследил нить? Хотя, кто бы сомневался.

Да и в ней тоже слил,

Если ты повторишь это сто раз, то даже сам поверишь. Аутотренинг — великая сила.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

это ты не знаешь, о чём говоришь: во времена 8086 не было огромных кешей на кристалле

Потому что не было необходимости в кеше.

гениальный аргумент! Вот и у Александра Невского не было никакой необходимости в танках-амфибиях. ☺

Действительно: подумаешь, Over9000 бойцов на Чудском Озере утонуло? Мы же всё равно победили!

drBatty ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.