Привет всем! Задача: 1. Написать процедуру знакового умножения, подобно IMUL 2. Написать процедуру беззнакового деления типа DIV 3. Написать процедуру остатка от деления Все это на целых 32битных числах. Вход: A, B Выход: C Написать эти процедуры, не используя MUL, IMUL, DIV, IDIV... Я написал эти три задачи через SHL, ADD, SUB. Хочу получить СУПЕР-ОПТИМАЛЬНЫЙ исходник! Может кто-то занимался этим??? Хочу так, как это делает проц. Могу выслать свой вариант, если это кому-то поможет упростить... Получилось оптимально, хочу еще!!! Но мне все же хочется увидеть СУПЕР-ОПТИМАЛЬНЫЙ вариант... З.Ы. Бывают же ситуации, когда есть сдвиги, логика, сложение, а хочется все остальное =)
Если именно самый оптимальный - то он сильно зависит от того на какое число умножать/делить/брать остаток. И потом - где критерий оптимальности? По скорости, по размеру кода или данных??? Например, деление и взятие остатка иногда "табличатся", но вот размеры этих табличек могут быть большими (для больших делителей), а сам алгоритм - простой... p.s. смахивает на курсовую или лабу...
Самые быстрые аппаратные умножители - матричные - принципиально не эмулируются программно Учите схемотехнику Аппаратура вообще плохо эмулируется, т.к. работает параллельно, а не последовательно. Поэтому "как процессор" - не получится.
Меня посещала идея насчет таблиц... Но я хочу максимально приблизиться к жизни тех, кто имеет МК, имеет ADD, SHL, SHR... А хочет иметь DIV, MUL, IMUL....
Интересно! Поясни подробнее, почему нельзя достичь хорошей эмуляции? Примеры и т.д. Хотя бы мат.модель этого умножителя...
Code (Text): // Умножение int Mul(int A, int B) { // Перевод чисел в обычную форму bool f1 = (A < 0), f2 = (B < 0); A = f1 ? (-A) : A; B = f2 ? (-B) : B; // Ищем начало числа B int K; for(K = 30; K >= 0; K--) // 31 бит - знак, 30..0 биты - число if(B & (1 << K)) break; // Умножение int C = 0; while(K >= 0) { if(B & (1 << K)) C += A << K; K--; } // Перевод числа C в расширенную форму C = (f1 ^ f2) ? (-C) : C; return C; } Code (Text): // Деление unsigned int Div(unsigned int A, unsigned int B) { if(B == 0) { throw string("\n#Error: Division by zero!\n"); return 0; } // Ищем начало числа A int K; for(K = 31; K >= 0; K--) if(A & (1 << K)) break; // Деление unsigned int C = 0; while(A >= B) { unsigned int P = (B << K); if(P <= A) { C += 1 << K; A -= P; } K--; } return C; } Code (Text): //Остаток от деления: unsigned int Mod(unsigned int A, unsigned int B) { if(B == 0) { throw string("\n#Error: Division by zero!\n"); return 0; } if(A < B) return A; if(A == B ) return 0; // Ищем начало числа A int K; for(K = 31; K >= 0; K--) if(A & (1 << K)) break; // Деление while(A >= B) { int P = (B << K); if(P <= A) A -= P; K--; } return A; } Хочу сделать лучше, оптимальнее!!!!! Буду благодарен, если этот исходник будет сделан лучше... Исходник можно АСМ, можно СИ.... Люди, которые прогают дешевые МК должны сами делать MUL, DIV.... Они делают это супер-оптимально, по вполне понятным причинам Я не прогаю МК(это пока, на данный момент))). Но я хочу знать, как мне сделать СУПЕР-КРУТОЕ *,/,% ручками...
Я же говорю - он работает параллельно, а не последовательно. Матричный умножитель - асинхроннрое устройство, он построен не на базе n-разрядного сумматора и счётчика, а из n^2 одноразрядных сумматоров, соеденённых в виде матрицы. Все n^2 сумматоров работают параллельно, скорость умножения - 2n скоростей работы одноразрядного сумматора. Сейчас посмотрю, что в сети есть хорошего.. А если на бумаге - например книжка Угрюмов Е.П. "Цифровая схемотехника" - вроде не плохая, и умножитель там есть точно. Сам её не читал, преподаватель советовал
http://www.andraka.com/multipli.htm, я имел ввиду "Carry Save Array Multipliers". Объяснений там конечно нет, зато картинка есть Только насчёт самых быстрых я возможно поторопился, там ещё несколько интересных вариантов описано, сам пока не разобрался Но все такие варианты программно не реализуемы по определению.
sergh Думаю, что самый быстрый умножитель - это обычный аналоговый транзистор Только данные сначала нужно через ADC пропустить, а потом обратно через DAC оцифровать.
microprogs Если хочешь приблизится к аппаратной реализации умножений/делений - пиши на verilog'е ну или хотя бы на vhdl. Там и пригодятся всякие блочно/параллельные схемы... Как человек программировавший, наверное, десятки разных мк, могу сказать, что "супер-навороченного" там ничего нет. У каждого мк свой подход к этим процедурам, т.к. наборы команд и скорости их выполнения сильно разные (есть мк которые не умеют, например, сдвигать на произвольные значения, а есть у которых сдвиг совмещен со сложением, что удобно). Единого оптимального алгоритма НЕТ и быть и не может. А где-то можно и твой алгоритм считать достаточно оптимальным. p.s. а вообще а чем проблема? возьми ассемблерные исходники библиотек от разных мк и посмотри как там всякое взятие остатка сделано, начни с pic16ххх, а потом глянь на adsp21xxx и попробуй после этого соорудить единый алгоритм ...
А почему "ну или хотя бы"? Verilog - сильно лучше? Не как наезд, а как вопрос - я только VHDL-ем более-менее владею.
Verilog vs. VHDL - это примерно как Turbo Pascal vs. Delphi. С одной стороны, Verilog лучше, но с другой - этот язык мёртв.
Ну хоть немного поподробнее проясни-то! Почему лучше, почему мёртв? Не обязательно многостраничный трактат с описанием и сравнением, я немного в теме, общих слов скорее всего хватит. Особенно про мёртв - до сих пор такого мнения не слышал, даже среда, в которой я работал (Quartus Altera 5.0) Verilog подерживает.
sergh googl: VHDL vs. Verilog В IEEE решили, что Verilog - отстой, тормозящий развитие VLSI/ASIC, и приняли стандарт VHDL. Но почему-то 10 лет спустя разработчики продолжают пользоваться Verilog'ом. За что так не любят Verilog? - думаю, что за "низкоуровневость". Я с этим мнением тоже не согласен, хотя использую VHDL, идя на поводу у умных дядек из IEEE. В Альтере не дураки, чтобы прекращать поддержку довольно популярного языка. А поддержка полного стандарта VHDL (и нормальной оптимизации) им оказалась не под силу - вот и акцентируют использование Verilog'а. У Xilinx дела обстоят немного лучше.
Хм... Бау =) Только не мучают, а я сам придумал эту задачу! =) И преподу ее порекомендовал, чтобы вся группа помучалась =), т.к. я хочу реальный кодинг, хоть в ЯВУ, хоть в Асме!!! А реальный кодинг никто кроме себя самого не сделает А универ - это банальный закос от армии, там никогда не будет того, что есть в серии книг, и то что может встретиться в жизни... Универ - всего лишь направление, а вот развитие направления - это личное дело Поэтому кодить-кодить и еще раз кодить на всем!!! Под все!!! =)