SORU
19 Aralık 2012, ÇARŞAMBA


Neden ekleme montaj açıklamaları oluşturulan kod içinde böyle bir radikal değişikliğe neden olur mu?

Yani, bu kodu vardı:

constexpr unsigned N = 1000;
void f1(char* sum, char* a, char* b) {
    for(int i = 0; i < N;   i) {
        sum[i] = a[i]   b[i];
    }
}

void f2(char* sum, char* a, char* b) {
    char* end = sum   N;
    while(sum != end) {
        *sum   = *a     *b  ;
    }
}

GCC 4.7.2 oluşturmak kodunu görmek istedim. g -march=native -O3 -masm=intel -S a.c -std=c 11 yaptım Ve şu çıktıyı aldım:

        .file   "a.c  "
        .intel_syntax noprefix
        .text
        .p2align 4,,15
        .globl  _Z2f1PcS_S_
        .type   _Z2f1PcS_S_, @function
_Z2f1PcS_S_:
.LFB0:
        .cfi_startproc
        lea     rcx, [rdx 16]
        lea     rax, [rdi 16]
        cmp     rdi, rcx
        setae   r8b
        cmp     rdx, rax
        setae   cl
        or      cl, r8b
        je      .L5
        lea     rcx, [rsi 16]
        cmp     rdi, rcx
        setae   cl
        cmp     rsi, rax
        setae   al
        or      cl, al
        je      .L5
        xor     eax, eax
        .p2align 4,,10
        .p2align 3
.L3:
        movdqu  xmm0, XMMWORD PTR [rdx rax]
        movdqu  xmm1, XMMWORD PTR [rsi rax]
        paddb   xmm0, xmm1
        movdqu  XMMWORD PTR [rdi rax], xmm0
        add     rax, 16
        cmp     rax, 992
        jne     .L3
        mov     ax, 8
        mov     r9d, 992
.L2:
        sub     eax, 1
        lea     rcx, [rdx r9]
        add     rdi, r9
        lea     r8, [rax 1]
        add     rsi, r9
        xor     eax, eax
        .p2align 4,,10
        .p2align 3
.L4:
        movzx   edx, BYTE PTR [rcx rax]
        add     dl, BYTE PTR [rsi rax]
        mov     BYTE PTR [rdi rax], dl
        add     rax, 1
        cmp     rax, r8
        jne     .L4
        rep
        ret
.L5:
        mov     eax, 1000
        xor     r9d, r9d
        jmp     .L2
        .cfi_endproc
.LFE0:
        .size   _Z2f1PcS_S_, .-_Z2f1PcS_S_
        .p2align 4,,15
        .globl  _Z2f2PcS_S_
        .type   _Z2f2PcS_S_, @function
_Z2f2PcS_S_:
.LFB1:
        .cfi_startproc
        lea     rcx, [rdx 16]
        lea     rax, [rdi 16]
        cmp     rdi, rcx
        setae   r8b
        cmp     rdx, rax
        setae   cl
        or      cl, r8b
        je      .L19
        lea     rcx, [rsi 16]
        cmp     rdi, rcx
        setae   cl
        cmp     rsi, rax
        setae   al
        or      cl, al
        je      .L19
        xor     eax, eax
        .p2align 4,,10
        .p2align 3
.L17:
        movdqu  xmm0, XMMWORD PTR [rdx rax]
        movdqu  xmm1, XMMWORD PTR [rsi rax]
        paddb   xmm0, xmm1
        movdqu  XMMWORD PTR [rdi rax], xmm0
        add     rax, 16
        cmp     rax, 992
        jne     .L17
        add     rdi, 992
        add     rsi, 992
        add     rdx, 992
        mov     r8d, 8
.L16:
        xor     eax, eax
        .p2align 4,,10
        .p2align 3
.L18:
        movzx   ecx, BYTE PTR [rdx rax]
        add     cl, BYTE PTR [rsi rax]
        mov     BYTE PTR [rdi rax], cl
        add     rax, 1
        cmp     rax, r8
        jne     .L18
        rep
        ret
.L19:
        mov     r8d, 1000
        jmp     .L16
        .cfi_endproc
.LFE1:
        .size   _Z2f2PcS_S_, .-_Z2f2PcS_S_
        .ident  "GCC: (GNU) 4.7.2"
        .section        .note.GNU-stack,"",@progbits

Döngüler cesetlerin nereye gittiğini bilmek için bazı işaretler eklemeye karar verdim derleme okuma berbatım:

constexpr unsigned N = 1000;
void f1(char* sum, char* a, char* b) {
    for(int i = 0; i < N;   i) {
        asm("# im in ur loop");
        sum[i] = a[i]   b[i];
    }
}

void f2(char* sum, char* a, char* b) {
    char* end = sum   N;
    while(sum != end) {
        asm("# im in ur loop");
        *sum   = *a     *b  ;
    }
}

Ve bu GCC tükürdü:

    .file   "a.c  "
    .intel_syntax noprefix
    .text
    .p2align 4,,15
    .globl  _Z2f1PcS_S_
    .type   _Z2f1PcS_S_, @function
_Z2f1PcS_S_:
.LFB0:
    .cfi_startproc
    xor eax, eax
    .p2align 4,,10
    .p2align 3
.L2:
#APP
# 4 "a.c  " 1
    # im in ur loop
# 0 "" 2
#NO_APP
    movzx   ecx, BYTE PTR [rdx rax]
    add cl, BYTE PTR [rsi rax]
    mov BYTE PTR [rdi rax], cl
    add rax, 1
    cmp rax, 1000
    jne .L2
    rep
    ret
    .cfi_endproc
.LFE0:
    .size   _Z2f1PcS_S_, .-_Z2f1PcS_S_
    .p2align 4,,15
    .globl  _Z2f2PcS_S_
    .type   _Z2f2PcS_S_, @function
_Z2f2PcS_S_:
.LFB1:
    .cfi_startproc
    xor eax, eax
    .p2align 4,,10
    .p2align 3
.L6:
#APP
# 12 "a.c  " 1
    # im in ur loop
# 0 "" 2
#NO_APP
    movzx   ecx, BYTE PTR [rdx rax]
    add cl, BYTE PTR [rsi rax]
    mov BYTE PTR [rdi rax], cl
    add rax, 1
    cmp rax, 1000
    jne .L6
    rep
    ret
    .cfi_endproc
.LFE1:
    .size   _Z2f2PcS_S_, .-_Z2f2PcS_S_
    .ident  "GCC: (GNU) 4.7.2"
    .section    .note.GNU-stack,"",@progbits

Bu oldukça kısa ve SIMD talimatları eksikliği gibi bazı önemli farklılıklar vardır. Aynı çıktı, bir yerde ortasındaki bir yorum bekliyordum. Bazı yanlış varsayım burada mı yapıyorum? Gds'ler doktoru kanamayla yorum tarafından engellendi mi?

CEVAP
19 Aralık 2012, ÇARŞAMBA


Optimizasyon ile etkileşimler aşağı belgelerinde "Assembler Instructions with C Expression Operands" sayfası yaklaşık yarım açıklanmıştır.

GCC yok etmeye çalışın herhangi bir gerçek derleme içinde asm; tek şey biliyor hakkında içerik ne demek (isteğe bağlı olarak) söyle içinde çıkış ve giriş işlenen şartname ve kemik kıran kayıt listesi.

Özellikle, not:

Herhangi bir çıkış işlenen olmadan asm talimatı asm uçucu bir talimat aynı şekilde muamele edilecektir.

ve

volatile anahtar kelime talimat yan etkileri önemli olduğunu gösterir [...]

Döngü içinde asm varlığı GCC yan etkisi yoktur kabul eder, çünkü optimizasyonu bir vectorisation tutuk.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Commander Chalkboard

    Commander Ch

    20 Ocak 2014
  • DrePwn

    DrePwn

    22 Temmuz 2011
  • Miles Fisher

    Miles Fisher

    8 NİSAN 2009