Click here to Skip to main content
15,901,920 members

Performance was not as expected

Latest Revision
Hi everyone

I wrote a function to get the exponent of a number power of two. Here is the code:

C++
int exp = 0;
while((n = n / 2) > 0) {
//while((n = n >> 1) > 0) {
	exp++;
}
return exp;


Then came to mind, "Well, let's replace that division operator to the shift operator, to improve performance".

The result was not the expected.

Using the division operator, the code takes about 1 second; using the shift operator, the code takes about 1.3 seconds, on same conditions.

In debug mode, I checked the disassmebly code gave me by Visual Studio (Note: I don't understand nothing about assembly language). I noticed that the assembly code was the same, except when I am using the division operator, there are two more instruction.

So, can anyone explain to me the reason of this time execution difference? I expected, in worst case, the same execution time.

Thanks in advance
Filipe Marques

UPDATE 2: Add the full asm code for release mode.

For the divion operator:
ASM
PUBLIC  ?get_exponent@@YAHH@Z               ; get_exponent
; Function compile flags: /Ogtp
;   COMDAT ?get_exponent@@YAHH@Z
_TEXT   SEGMENT
?get_exponent@@YAHH@Z PROC              ; get_exponent, COMDAT
; _n$ = eax

; 124  :    int exp = 0;
; 125  :    while((n = n / 2) > 0) {

    cdq
    sub eax, edx
    sar eax, 1
    xor ecx, ecx
    test    eax, eax
    jle SHORT $LN7@get_expone
    npad    5
$LL2@get_expone:
    cdq
    sub eax, edx
    sar eax, 1

; 126  :    //while((n = n >> 1) > 0) {
; 127  :        exp++;

    inc ecx
    test    eax, eax
    jg  SHORT $LL2@get_expone
$LN7@get_expone:

; 128  :    }
; 129  :    return exp;

    mov eax, ecx

; 130  : }

    ret 0
?get_exponent@@YAHH@Z ENDP              ; get_exponent


For shift operator:
ASM
PUBLIC  ?get_exponent@@YAHH@Z               ; get_exponent
; Function compile flags: /Ogtp
;   COMDAT ?get_exponent@@YAHH@Z
_TEXT   SEGMENT
?get_exponent@@YAHH@Z PROC              ; get_exponent, COMDAT
; _n$ = ecx

; 124  :    int exp = 0;
; 125  :    //while((n = n / 2) > 0) {
; 126  :    while((n = n >> 1) > 0) {

    sar ecx, 1
    xor eax, eax
    test    ecx, ecx
    jle SHORT $LN1@get_expone
$LL2@get_expone:
    sar ecx, 1

; 127  :        exp++;

    inc eax
    test    ecx, ecx
    jg  SHORT $LL2@get_expone
$LN1@get_expone:

; 128  :    }
; 129  :    return exp;
; 130  : }

    ret 0
?get_exponent@@YAHH@Z ENDP              ; get_exponent
Posted 26-Jan-13 6:59am by Filipe Marques.
Tags: ,