2015-07-26 7 views
1

Я работал с PIC18f4550, и программа имеет решающее значение для скорости. когда я умножаю две плавающие переменные, для выполнения умножения потребовалось около 150 циклов ПИК. Я измеряю его с помощью таймера PIC18f45501.Почему добавление с плавающей запятой занимает больше времени, чем умножение

variable_1 = variable_2 * variable_3; // took 140 cycles to implement 

С другой стороны, когда я добавляю те же две переменные, ПИК занимал 280 циклов, чтобы выполнить добавление.

variable_1 = variable_2 + variable_3; // took 280 cycles to implement 

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

+0

Умножение может быть проще сделать, чем сложение, так как смена битов позволяет мгновенно удвоить, так что 50 x 4 можно сделать очень быстро, так как вы просто сдвигаете все биты более 2. 50 x 10 будет (50 сдвинуто на 3 (50 * 8) + (50 сдвинутых один раз (50 * 2) –

+0

Ваши данные показывают, что операции с плавающей запятой на этой платформе эмулируются. Я работал над несколькими эмуляциями с плавающей запятой, прежде чем на нескольких аппаратных платформах (включая x86 и ARM), и, по моему опыту, если процессор предлагает инструкцию с быстрым целым умножением, умножение с плавающей запятой может быть быстрее, чем добавление. Для добавления требуется различать несколько случаев: Является ли это эффективным сложение или вычитание? велика по величине? Разница в экспонентах большая или малая («ближний» и «далекий» случай)? Умножение - это прямой код. – njuffa

+0

Я откопал некоторые исторические данные в одном из моих пакетов эмуляции с плавающей запятой, и он предполагает, что при наличии краткой команды с быстрым целым числом умноженное умножение с плавающей запятой может быть примерно на 10% быстрее, чем эмулированное добавление с плавающей запятой. [Статья о эмуляции с плавающей запятой в ARM] (http://www.dec.usc.es/arith16/papers/paper-131.ps) показывает пропускную способность при умножении на 1.28x, добавляя пропускную способность для * двойной точности *. Коэффициент 2x, который вы наблюдаете, кажется чрезмерным для меня, возможно, указывая, что добавление не эмулируется так эффективно, как могло бы быть. – njuffa

ответ

3

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

Поскольку ПИК, по-видимому, имеет небольшой аппаратный множитель, может быть неудивительно, что иногда умножение может быть более быстрым, чем выполнение многобайтового сдвига (особенно, если ПИК имеет только инструкции по сдвигу бит).

Если процессор не имеет прямой поддержки, то плавающая точка всегда медленная, и вам, безусловно, следует подумать о том, чтобы организовать код для использования фиксированной точки, если это вообще возможно. Избавление от библиотеки с плавающей запятой, вероятно, освободит и много кодового пространства.

+0

[Справочное руководство для PIC18f4550] (http://www.microchip.com/downloads/en/DeviceDoc/39632e.pdf) показано наличие 8х8-> 16-битного однотактного множителя. Поддерживаются однобитовые вращения, необходимые для сдвига многобайтового количества.Из моего опыта работы с 8086, который также не поддерживал многобитовые сдвиги, ясно, что сдвиги, необходимые во время выравнивания мантиссы, относительно дороги, но сдвиг должен использовать поэтапный сдвиг по ходу регистров только с оставшимся числом сдвига (по модулю 8) с 1-битным сдвигом/вращением. Поэтому, хотя ожидается, что ожидается медленнее, я бы не ожидал, что он будет медленнее на 2x. – njuffa

+0

Уточнение: у 8086 не было баррель-переключателя, поэтому не было поддержки * немедленного * сдвига, отличного от 1. Однако многобитовое смещение поддерживалось инструкциями с использованием микрокодированного цикла с использованием регистра 'CL', который, однако, был медленнее * чем эквивалентная последовательность инструкций 'SHR/ROR/RCR reg, 1'. – njuffa