Разница в производительности с приведением к удвоению и приращению - PullRequest
2 голосов
/ 02 апреля 2011

Я увеличиваю счетчик, который мне нужно будет использовать после цикла в двойной арифметике.Итак, что вы ожидаете быстрее?(Или слишком близко, чтобы звонить?)

Код 1:

double dubs = 3.14159265;
double d;
for(d=0; d<BIGNUM; d++) { /* do stuff not depending on d */ }
dubs /= d;

Код 2:

double dubs = 3.14159265;
int i;
for(i=0; i<BIGNUM; i++) { /* do stuff not depending on i */ }
dubs /= (double) i;

И зависит ли это от размера BIGNUM?Я знаю, что это было бы незначительной разницей, но я просто задался вопросом в теории.

Бонусный вопрос: если бы это был C ++, какие-нибудь изменения в вашем ответе для использования static_cast?

- Edit--

Хорошо, вот пример кода и ассемблер:

#define BIGNUM 1000000000
#define NUMLOOPS 1000

double test1()
{
    double dubs = 3.14159265;
    double d;
    int k = 1;
    for(d=0; d<BIGNUM; d++) { k*= 2; }
    dubs /= d;
    return dubs;
}

double test2()
{
    double dubs = 3.14159265;
    int i;
    int k = 1;
    for(i=0; i<BIGNUM; i++) { k*= 2; }
    dubs /= (double)i;
    return dubs;
}

int main()
{
    double d1=0;
    double d2=0;
    int i;
    for(i=0; i<NUMLOOPS; i++)
    {
        d1 += test1();
        d2 += test2();
    }
}


_test1:
LFB2:
    pushq   %rbp
LCFI0:
    movq    %rsp, %rbp
LCFI1:
    subq    $48, %rsp
LCFI2:
    call mcount
    movabsq $4614256656543962353, %rax
    movq    %rax, -16(%rbp)
    movl    $1, -4(%rbp)
    movl    $0, %eax
    movq    %rax, -24(%rbp)
    jmp L2
L3:
    sall    -4(%rbp)
    movsd   -24(%rbp), %xmm0
    movsd   LC2(%rip), %xmm1
    addsd   %xmm1, %xmm0
    movsd   %xmm0, -24(%rbp)
L2:
    movsd   -24(%rbp), %xmm1
    movsd   LC3(%rip), %xmm0
    ucomisd %xmm1, %xmm0
    ja  L3
    movsd   -16(%rbp), %xmm0
    divsd   -24(%rbp), %xmm0
    movsd   %xmm0, -16(%rbp)
    movq    -16(%rbp), %rax
    movq    %rax, -40(%rbp)
    movsd   -40(%rbp), %xmm0
    leave
    ret


_test2:
LFB3:
    pushq   %rbp
LCFI3:
    movq    %rsp, %rbp
LCFI4:
    subq    $32, %rsp
LCFI5:
    call mcount
    movabsq $4614256656543962353, %rax
    movq    %rax, -16(%rbp)
    movl    $1, -8(%rbp)
    movl    $0, -4(%rbp)
    jmp L7
L8:
    sall    -8(%rbp)
    incl    -4(%rbp)
L7:
    cmpl    $99999, -4(%rbp)
    jle L8
    cvtsi2sd    -4(%rbp), %xmm1
    movsd   -16(%rbp), %xmm0
    divsd   %xmm1, %xmm0
    movsd   %xmm0, -16(%rbp)
    movq    -16(%rbp), %rax
    movq    %rax, -24(%rbp)
    movsd   -24(%rbp), %xmm0
    leave
    ret

Тест в данный момент выполняется ....

1 Ответ

1 голос
/ 02 апреля 2011

Двойной код, вероятно, не имеет значения, но если бы вы использовали float, первый фрагмент кода может даже не работать.Из-за ограниченной точности, через некоторое время увеличение float не изменит его значения.Конечно, с (целыми) целочисленными типами вы получаете UB при переполнении, что, возможно, еще хуже.

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

...