Короткий против Int Gcc

Я ожидал, что Loop2 в следующей программе займет больше времени по сравнению с Loop1. Но даже после включения оптимизации (gcc -O2) я вижу, что оба цикла занимают почти одинаковое время. Почему это так в моей системе с sizeof(int)=4 и sizeof(short)=2 ? Я ожидал, что компилятор поставит короткую инструкцию умножения для умножения шорт и, следовательно, меньшего времени.

#include <stdio.h>
#include <time.h>

float DiffTime(struct timespec Start,struct timespec Stop);

main ()
{
    struct timespec start,stop;    
    int    i;  
    short  a,b,c;
    int    p,q,r;

    a=1;
    b=2;
    c=3;
    p=1;
    q=2;
    r=3;
    clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
    for(i=0;i<1000000;i++) // Loop1
    {
        a=b*a;
    }
    clock_gettime (CLOCK_THREAD_CPUTIME_ID, &stop);
    printf("Time taken %11.9fs\n",DiffTime(start,stop));
    clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
    for(i=0;i<1000000;i++) // Loop2
    {
        p=q*p;
    }
    clock_gettime (CLOCK_THREAD_CPUTIME_ID, &stop);
    printf("Time taken %11.9fs\n",DiffTime(start,stop));

    printf("%d,%d\n",a,p);        

}

float DiffTime(struct timespec Start,struct timespec Stop)    
{
 long nTime1,nTime2;
 nTime1=Start.tv_sec*1000000000 + Start.tv_nsec ;
 nTime2=Stop.tv_sec*1000000000 + Stop.tv_nsec ;
 return((float)(nTime2-nTime1)/1000000000);
}

person Jean    schedule 21.12.2012    source источник
comment
Слово «короткий» в коротком умножении не относится к времени выполнения операции...   -  person    schedule 21.12.2012
comment
Можете ли вы объяснить, почему вы ожидали, что shorts будут быстрее?   -  person Jonathan Wood    schedule 21.12.2012
comment
как вы думаете, почему 4-байтовый imul займет больше времени, чем 2-байтовый на современном процессоре?   -  person AShelly    schedule 21.12.2012
comment
Как многие говорили, для x86 нет 16-битной инструкции умножения. Но почему ? Теперь это становится комп-архивным вопросом. Предполагая последовательный умножитель, 16-битное умножение может быть выполнено быстрее. Любые подсказки, почему они не реализовали 16-битное умножение?   -  person Jean    schedule 21.12.2012


Ответы (5)


Не ожидайте, что сможете предугадать свой компилятор, когда дело доходит до производительности. Единственное, чего вы должны ожидать, — это лучшие времена большого O, основанные на ваших алгоритмах.

Если в руководстве сказано, что размер типа данных равен X, это все, что он утверждает, и это все, что вам следует ожидать.

person RonaldBarzell    schedule 21.12.2012
comment
Не ожидайте, что сможете угадать ваш компилятор - и вот как вы получили мой голос. - person ; 21.12.2012
comment
Есть много случаев, когда компилятор недостаточно хорош. Из того, что я испытал, компиляторы могут правильно получить до 80-90% общей производительности. Все, что осталось, зависит от программиста. Я говорю об оптимизации алгоритма, а не о выборе - person Gustavo Litovsky; 22.12.2012
comment
@gl3829: я поверю тебе на слово; Я не заглядываю под капот, потому что знаю, что компилятор работает лучше, чем я, и я думаю, что это пустая трата времени. Если мой код слишком медленный, я смотрю на алгоритм. Если я пробую оптимизацию глазка, я делаю это, зная, что бросаю кубик, и я не беспокоюсь, если это не сработает, это был выстрел в темноте с самого начала. Я также знаю о связанных с этим рисках, таких как изменения реализации, делающие оптимизацию недействительной. - person RonaldBarzell; 22.12.2012

Я не удивлюсь, если после включения оптимизации оба цикла пусты. Вы пытались увеличить N в 10 раз и посмотреть, есть ли различия?

person AShelly    schedule 21.12.2012
comment
Даже когда я использую вывод с помощью printf? - person Jean; 21.12.2012
comment
Простой оптимизатор мог бы распознать, что в цикле ничего не меняется, и выполнить умножение только один раз. Умный оптимизатор мог бы понять, что вообще ничего не меняется, и установить a и p на 6 во время компиляции. - person AShelly; 21.12.2012
comment
Да, это так. Это рекурсивное умножение. - person Jean; 21.12.2012
comment
ой, я прочитал это как a=b*c. Тем не менее, вывод printf постоянен и подлежит оптимизации. Это восходит к комментарию @RonaldBarzell: вы не можете предсказать, что сгенерирует оптимизатор, только то, что он выдаст правильный результат. - person AShelly; 21.12.2012

На большинстве 32-битных архитектур, включая x86, умножение 16-битных значений занимает столько же времени, сколько 32-битных значений. (Действительно, он, вероятно, будет использовать ту же самую инструкцию.)

person Community    schedule 21.12.2012

На большинстве аппаратных платформ будет только один тип целочисленного исполнительного блока, и он будет выполнять целочисленные операции независимо от размера за одно и то же количество циклов ЦП. Таким образом, умножение signed char, short, int, long long int займет одинаковое время, потому что это делает одно и то же оборудование.

person Sergey L.    schedule 21.12.2012

Как уже говорили люди, процессоры ALU имеют фиксированный размер и будут продвигать меньшие целые числа до этого предпочтительного размера. Современные процессоры имеют как минимум 32-битные ALU. Еще никто не упомянул, что на 32- или 64-битных машинах может даже случиться так, что использование более коротких типов будет генерировать более медленный код. Из-за некоторых эзотерических правил в некоторых случаях генератору кода может потребоваться добавить явные инструкции по расширению знака. У меня был такой эффект в Solaris на SPARC с gcc v3, который добавил в код множество 16-битных инструкций усечения, что сделало шорты заметно медленнее, чем использование int.

person Patrick Schlüter    schedule 21.12.2012