Click here to Skip to main content

Filipe Marques asked:

Open original thread
Hi everyone
 
I wrote a function to get the exponent of a number power of two. Here is the code:
 
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:
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:
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
Tags: C++, C

Preview



When answering a question please:
  1. Read the question carefully.
  2. Understand that English isn't everyone's first language so be lenient of bad spelling and grammar.
  3. If a question is poorly phrased then either ask for clarification, ignore it, or edit the question and fix the problem. Insults are not welcome.
Let's work to help developers, not make them feel stupid.
Please note that all posts will be submitted under the The Code Project Open License (CPOL).



Advertise | Privacy | Mobile
Web04 | 2.8.140921.1 | Last Updated 26 Mar 2009
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100