【问题标题】:Why does C program run Slower when a loop contains a condition当循环包含条件时,为什么 C 程序运行较慢
【发布时间】:2016-12-28 15:02:33
【问题描述】:

我根据收到的 cmets 重新表述这个问题。

我有一个循环运行 300 亿次并将值分配给使用 malloc() 分配的一块内存;

当循环包含条件时,它的运行速度比条件不存在时慢得多。查看以下场景:

场景 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

【问题讨论】:

  • 没有任何上下文我们只能猜测。一种猜测是 0 被用作某些字符串的终止字符,但如上所述,我们需要一些上下文。
  • 千里眼科正在休产假。所有关于非工作代码的问题都必须附有minimal reproducible example。管理层希望对由此造成的任何不便深表歉意。
  • 发布我们可以运行和编译的最小简化代码。如果你是对的,我预计投票率会很高。
  • 那是什么循环?
  • while (*n); 我猜...

标签: c pointers memory


【解决方案1】:

您可以使用 gcc -S -O3 查看生成的汇编程序。 以下是 Intel 盒子上的示例:

快速版本:

    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 指令)。但是,如果条件保持不变,则无法启动此优化 - 因为结果不同。

【讨论】:

    猜你喜欢
    • 2022-11-28
    • 1970-01-01
    • 2021-12-01
    • 2017-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多