Re[7]: 1000! и вывести дело на экран?
От: Balancer Россия http://balancer.da.ru
Дата: 15.02.03 16:43
Оценка:
M>Звучит убедительно. Правда, это на ассемблере. Как будет дело с "нормальными ЯВУ", не знаю.

За Дельфи не поручусь, хотя, вроде, Борданд там, наконец-то, смог разродиться неплохим компилятором, а вот компиляторц VC7 давно можно доверять

M>Нужно измерять. Интуиция мне подсказывает, что 16-бит разряды и 32-бит умножение будет быстрее 32-бит разрядов и 64-бит умножения.


#include <stdio.h>

void main(void)
{
    unsigned short a16,b16,c16,d16;
    unsigned long  a32,b32,c32,d32;
    scanf("%d %d"  ,&a16,&b16);
    scanf("%ld %ld",&a32,&b32);

    unsigned long tmp32=(unsigned long)a16*b16;
    d16=tmp32;
    c16=tmp32>>16;

    printf("%d %d\n", c16, d16);
    
    unsigned __int64 tmp64=(unsigned __int64)a32*b32;
    d32=tmp64;
    c32=tmp64>>32;

    printf("%ld %ld", c32, d32);
}


Имеем следующий ассемблерный код (только то, что интересно и несколько упрощено — имена переменных и т.п.):

; 10   :     unsigned long tmp32=(unsigned long)a16*b16;

    movzx   eax, _a16
    movzx   ecx, _b16
    imul    eax, ecx

; 11   :     d16=tmp32;
; 12   :     c16=tmp32>>16;
; 13   : 
; 14   :     printf("%d %d\n", c16, d16);

    movzx   edx, ax
    push    edx
    shr     eax, 16            ; 00000010H
    push    eax
    push    OFFSET s16 ; тут строка вывода
    call    _printf

; 15   :     
; 16   :     unsigned __int64 tmp64=(unsigned __int64)a32*b32;

    mov     eax, _a32
    mul     _b32

; 17   :     d32=tmp64;
; 18   :     c32=tmp64>>32;
; 19   : 
; 20   :     printf("%ld %ld", c32, d32);

    push    eax
    push    edx
    push    OFFSET s32 ; тут строка вывода
    call    _printf


Как видно, даже по числу операций работа с long'ами оказывается выгоднее. Ну неродные для IA32 16-битные числа А если ещё учесть, что за одну операцию обрабатывается вдвое большее число, то выигрышь становится совсем серьёзным

Хотя при отработке этого примера, едва ли не в первый раз столкнулся со случаем, который VC7 не осилил Я изначально делал разбиение произведения двойной точности на компоненты стандартной разрядности через / и % — хотел посмотреть, потянет ли оптимизацию компилятор. В случае 16-битных чисел результат был подобным, а вот для 32-х битных он вызвал библиотечную подпрограмму деления 64-хбитного числа... Пришлось пример оптимизировать уже вручную
...Глубина-глубина, я не твой...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.