首页 > 解决方案 > if 语句和 mod(SIZE) 之间的效率差异

问题描述

研究我发现使用(i+1)mod(SIZE)来在元素数组中执行循环。所以我想知道这种方法是否比 if 语句更有效......


例如:

#define SIZE 15

int main(int argc, char *argv[]) {
    int items[SIZE];

    for(int i = 0; items[0] < 5; i = (i + 1) % SIZE) items[i] += 1;

    return 0;
}

它比(?)更有效:

#define SIZE 15

int main(int argc, char *argv[]) {
    int items[SIZE];

    for(int i = 0; items[0] < 5; i++) {
        if(i == SIZE) i = 0;
        items[i] += 1;
    }

    return 0;
}

感谢您的回答和您的时间。

标签: cperformanceif-statementprocessing-efficiency

解决方案


您可以在线检查程序集(即此处)。结果取决于架构和优化,但如果没有优化并且对于带有 GCC 的 x64,您会得到此代码(作为一个简单示例)。

示例 1:

main:
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-68], edi
        mov     QWORD PTR [rbp-80], rsi
        mov     DWORD PTR [rbp-4], 0
.L3:
        mov     eax, DWORD PTR [rbp-64]
        cmp     eax, 4
        jg      .L2
        mov     eax, DWORD PTR [rbp-4]
        cdqe
        mov     eax, DWORD PTR [rbp-64+rax*4]
        lea     edx, [rax+1]
        mov     eax, DWORD PTR [rbp-4]
        cdqe
        mov     DWORD PTR [rbp-64+rax*4], edx
        mov     eax, DWORD PTR [rbp-4]
        add     eax, 1
        movsx   rdx, eax
        imul    rdx, rdx, -2004318071
        shr     rdx, 32
        add     edx, eax
        mov     ecx, edx
        sar     ecx, 3
        cdq
        sub     ecx, edx
        mov     edx, ecx
        mov     DWORD PTR [rbp-4], edx
        mov     ecx, DWORD PTR [rbp-4]
        mov     edx, ecx
        sal     edx, 4
        sub     edx, ecx
        sub     eax, edx
        mov     DWORD PTR [rbp-4], eax
        jmp     .L3
.L2:
        mov     eax, 0
        pop     rbp
        ret

示例 2:

main:
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-68], edi
        mov     QWORD PTR [rbp-80], rsi
        mov     DWORD PTR [rbp-4], 0
.L4:
        mov     eax, DWORD PTR [rbp-64]
        cmp     eax, 4
        jg      .L2
        cmp     DWORD PTR [rbp-4], 15
        jne     .L3
        mov     DWORD PTR [rbp-4], 0
.L3:
        mov     eax, DWORD PTR [rbp-4]
        cdqe
        mov     eax, DWORD PTR [rbp-64+rax*4]
        lea     edx, [rax+1]
        mov     eax, DWORD PTR [rbp-4]
        cdqe
        mov     DWORD PTR [rbp-64+rax*4], edx
        add     DWORD PTR [rbp-4], 1
        jmp     .L4
.L2:
        mov     eax, 0
        pop     rbp
        ret

你看,对于 x86 的特定情况,没有模数的解决方案要短得多。


推荐阅读