2016-12-28 37 views
-3

我正在根據收到的意見重新編寫此問題。我有一個循環,運行300億次,併爲使用malloc()分配的內存塊分配值;爲什麼C程序在循環包含條件時運行速度更慢

當循環包含一個條件時,它會比條件不存在時慢得多。查看以下情形:

情形A:條件存在且程序是緩慢(43秒)

情形B:條件是不存在,並且程序的速度要快得多(4秒)

// gcc -O3 -c block.c && gcc -o block block.o 



#include <stdio.h> 
#include <stdlib.h> 


#define LEN 3000000000 

int main (int argc, char** argv){ 

    long i,j; 

    unsigned char *n = NULL; 
    unsigned char *m = NULL; 

    m = (unsigned char *) malloc (sizeof(char) * LEN); 

    n = m; 

    srand ((unsigned) time(NULL)); 

    int t = (unsigned) time(NULL); 

    for (j = 0; j < 10; j++){ 

     n = m; 

     for (i = 0; i < LEN; i++){ 


      //////////// A: THIS IS SLOW 
      /* 
      if (i % 2){ 
       *n = 1;   

      } else { 
       *n = 0; 
      } 
      */ 
      /////////// END OF A 


      /////////// B: THIS IS FAST 

      *n = 0; 

      i % 2; 

      *n = 1; 

      /////////// END OF B 

      n += 1; 

     } 
    } 


    printf("Done. %d sec \n", ((unsigned) time(NULL)) - t); 

    free(m); 

    return 0; 
} 

問候, KD

+1

沒有任何語境我們只能猜測。一個猜測是0被用作一些字符串的終止字符,但正如我們所說的,我們需要一些上下文。 – Gerhardh

+4

千里眼科正在休產假。所有關於非工作代碼的問題都必須附帶[mcve]。管理層希望爲造成的不便道歉。 –

+0

發佈我們可以運行和編譯的最簡化代碼。如果你是對的,我預測很多投票。 –

回答

0

您可以使用gcc -S -O3來看看生成的彙編程序。 這裏是在英特爾盒的例子:

快速版本:

movl %eax, %r12d 
    .p2align 4,,10 
    .p2align 3 
.L2: 
    movl $3000000000, %edx 
    movl $1, %esi 
    movq %rbp, %rdi 
    call memset 
    subq $1, %rbx 
    jne .L2 

慢版:

movl $10, %edi 
    movl %eax, %ebp 
    movl $3000000000, %esi 
    .p2align 4,,10 
    .p2align 3 
.L2: 
    xorl %edx, %edx 
    .p2align 4,,10 
    .p2align 3 
.L5: 
    movq %rdx, %rcx 
    andl $1, %ecx 
    movb %cl, (%rbx,%rdx) 
    addq $1, %rdx 
    cmpq %rsi, %rdx 
    jne  .L5 
    subq $1, %rdi 
    jne  .L2 

結論:編譯比你想象的更聰明。它能夠將內循環優化爲memset(因爲它在Intel上使用SSE/AVX或REP指令,所以速度更快)。但是,如果條件保持不變,則此優化無法啓動 - 因爲結果不同。

相關問題