寄存器的结构还是矩阵?

时间:2019-05-21 14:13:18

标签: c performance matrix struct

我想要一个包含4个字节地址和4个字节数据的寄存器。为此,我考虑过将其构建为结构数组(包含地址和数据作为成员)或矩阵中。这里是一个示例代码,用于测试我想要实现的目标:

#include <stdio.h>
#include <stdint.h>

void reg_init();
#define REG_SIZE 1
typedef struct Reg{
    uint8_t addr[4];
    uint8_t data[4];
} reg;

static reg reg_struct[REG_SIZE];
static uint8_t reg_matrix[REG_SIZE][8];


int main()
{
    int index=-1;
    reg_init();
    for(int i=0; i<REG_SIZE; i++)
    {
        uint8_t addr_to_check[4]={0x12,0x34,0x56,0x78};
        // FOR STRUCT
        for(int j=0; j<4; j++)
        {
            if(addr_to_check[j]!=reg_struct[i].addr[j]) break;
            if(j==3) index = i;
        }

        //FOR MATRIX
        for(int j=0; j<4; j++)
        {
            if(addr_to_check[j]!=reg_matrix[i][j]) break;
            if(j==3) index = i;
        }
    }
    if (index<0) printf("Address not found\n");
    else printf("Address at index: %i",index);
    return 0;
}
void reg_init()
{
    // Register init for testing
    reg_struct[0].addr[0] = 0x12;
    reg_struct[0].addr[1] = 0x34;
    reg_struct[0].addr[2] = 0x56;
    reg_struct[0].addr[3] = 0x78;
    reg_struct[0].data[0] = 0x01;
    reg_struct[0].data[1] = 0x02;
    reg_struct[0].data[2] = 0x03;
    reg_struct[0].data[3] = 0x04;
    reg_matrix[0][0] = 0x12;
    reg_matrix[0][1] = 0x34;
    reg_matrix[0][2] = 0x56;
    reg_matrix[0][3] = 0x78;
    reg_matrix[0][4] = 0x01;
    reg_matrix[0][5] = 0x02;
    reg_matrix[0][6] = 0x03;
    reg_matrix[0][7] = 0x04;
}

该示例仅显示了一个单位大小的寄存器,但是大小会大得多(最多8个字节)。总的来说,我对性能方面的优化很感兴趣。使用一个或另一个真的很在乎,还是编译器会构建相同的机器代码?

1 个答案:

答案 0 :(得分:1)

下面是使用Visual Studio 2019创建的上述代码的汇编。
查看记录行号; Line 50; Line 51,看起来编译器已经为矩阵和结构创建了相同的汇编代码。

; Listing generated by Microsoft (R) Optimizing Compiler Version 19.20.27508.1 

    TITLE   D:\main.c
    .686P
    .XMM
    include listing.inc
    .model  flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC  ___local_stdio_printf_options
PUBLIC  __vfprintf_l
PUBLIC  _printf
PUBLIC  _reg_init
PUBLIC  _main
EXTRN   ___acrt_iob_func:PROC
EXTRN   ___stdio_common_vfprintf:PROC
_DATA   SEGMENT
COMM    ?_OptionsStorage@?1??__local_stdio_printf_options@@9@9:QWORD                            ; `__local_stdio_printf_options'::`2'::_OptionsStorage
_DATA   ENDS
_BSS    SEGMENT
_reg_struct DQ  01H DUP (?)
_reg_matrix DB  08H DUP (?)
_BSS    ENDS
_DATA   SEGMENT
$SG8132 DB  'Address not found', 0aH, 00H
    ORG $+1
$SG8133 DB  'Address at index: %i', 00H
_DATA   ENDS
; Function compile flags: /Odtp
_TEXT   SEGMENT
_index$ = -20                       ; size = 4
_addr_to_check$1 = -16                  ; size = 4
_j$2 = -12                      ; size = 4
_j$3 = -8                       ; size = 4
_i$4 = -4                       ; size = 4
_main   PROC
; File D:\main.c
; Line 16
    push    ebp
    mov ebp, esp
    sub esp, 20                 ; 00000014H
; Line 17
    mov DWORD PTR _index$[ebp], -1
; Line 18
    call    _reg_init
; Line 19
    mov DWORD PTR _i$4[ebp], 0
    jmp SHORT $LN4@main
$LN2@main:
    mov eax, DWORD PTR _i$4[ebp]
    add eax, 1
    mov DWORD PTR _i$4[ebp], eax
$LN4@main:
    cmp DWORD PTR _i$4[ebp], 1
    jge $LN3@main
; Line 21
    mov BYTE PTR _addr_to_check$1[ebp], 18  ; 00000012H
    mov BYTE PTR _addr_to_check$1[ebp+1], 52    ; 00000034H
    mov BYTE PTR _addr_to_check$1[ebp+2], 86    ; 00000056H
    mov BYTE PTR _addr_to_check$1[ebp+3], 120   ; 00000078H
; Line 23
    mov DWORD PTR _j$3[ebp], 0
    jmp SHORT $LN7@main
$LN5@main:
    mov ecx, DWORD PTR _j$3[ebp]
    add ecx, 1
    mov DWORD PTR _j$3[ebp], ecx
$LN7@main:
    cmp DWORD PTR _j$3[ebp], 4
    jge SHORT $LN6@main
; Line 25
    mov edx, DWORD PTR _j$3[ebp]
    movzx   eax, BYTE PTR _addr_to_check$1[ebp+edx]
    mov ecx, DWORD PTR _j$3[ebp]
    mov edx, DWORD PTR _i$4[ebp]
    movzx   ecx, BYTE PTR _reg_struct[ecx+edx*8]
    cmp eax, ecx
    je  SHORT $LN11@main
    jmp SHORT $LN6@main
$LN11@main:
; Line 26
    cmp DWORD PTR _j$3[ebp], 3
    jne SHORT $LN12@main
    mov edx, DWORD PTR _i$4[ebp]
    mov DWORD PTR _index$[ebp], edx
$LN12@main:
; Line 27
    jmp SHORT $LN5@main
$LN6@main:
; Line 30
    mov DWORD PTR _j$2[ebp], 0
    jmp SHORT $LN10@main
$LN8@main:
    mov eax, DWORD PTR _j$2[ebp]
    add eax, 1
    mov DWORD PTR _j$2[ebp], eax
$LN10@main:
    cmp DWORD PTR _j$2[ebp], 4
    jge SHORT $LN9@main
; Line 32
    mov ecx, DWORD PTR _j$2[ebp]
    movzx   edx, BYTE PTR _addr_to_check$1[ebp+ecx]
    mov eax, DWORD PTR _j$2[ebp]
    mov ecx, DWORD PTR _i$4[ebp]
    movzx   eax, BYTE PTR _reg_matrix[eax+ecx*8]
    cmp edx, eax
    je  SHORT $LN13@main
    jmp SHORT $LN9@main
$LN13@main:
; Line 33
    cmp DWORD PTR _j$2[ebp], 3
    jne SHORT $LN14@main
    mov ecx, DWORD PTR _i$4[ebp]
    mov DWORD PTR _index$[ebp], ecx
$LN14@main:
; Line 34
    jmp SHORT $LN8@main
$LN9@main:
; Line 35
    jmp $LN2@main
$LN3@main:
; Line 36
    cmp DWORD PTR _index$[ebp], 0
    jge SHORT $LN15@main
    push    OFFSET $SG8132
    call    _printf
    add esp, 4
    jmp SHORT $LN16@main
$LN15@main:
; Line 37
    mov edx, DWORD PTR _index$[ebp]
    push    edx
    push    OFFSET $SG8133
    call    _printf
    add esp, 8
$LN16@main:
; Line 38
    xor eax, eax
; Line 39
    mov esp, ebp
    pop ebp
    ret 0
_main   ENDP
_TEXT   ENDS
; Function compile flags: /Odtp
_TEXT   SEGMENT
_reg_init PROC
; File D:\main.c
; Line 41
    push    ebp
    mov ebp, esp
; Line 43
    mov eax, 8
    imul    ecx, eax, 0
    mov edx, 1
    imul    eax, edx, 0
    mov BYTE PTR _reg_struct[ecx+eax], 18   ; 00000012H
; Line 44
    mov ecx, 8
    imul    edx, ecx, 0
    mov eax, 1
    shl eax, 0
    mov BYTE PTR _reg_struct[edx+eax], 52   ; 00000034H
; Line 45
    mov ecx, 8
    imul    edx, ecx, 0
    mov eax, 1
    shl eax, 1
    mov BYTE PTR _reg_struct[edx+eax], 86   ; 00000056H
; Line 46
    mov ecx, 8
    imul    edx, ecx, 0
    mov eax, 1
    imul    ecx, eax, 3
    mov BYTE PTR _reg_struct[edx+ecx], 120  ; 00000078H
; Line 47
    mov edx, 8
    imul    eax, edx, 0
    mov ecx, 1
    imul    edx, ecx, 0
    mov BYTE PTR _reg_struct[eax+edx+4], 1
; Line 48
    mov eax, 8
    imul    ecx, eax, 0
    mov edx, 1
    shl edx, 0
    mov BYTE PTR _reg_struct[ecx+edx+4], 2
; Line 49
    mov eax, 8
    imul    ecx, eax, 0
    mov edx, 1
    shl edx, 1
    mov BYTE PTR _reg_struct[ecx+edx+4], 3
; Line 50
    mov eax, 8
    imul    ecx, eax, 0
    mov edx, 1
    imul    eax, edx, 3
    mov BYTE PTR _reg_struct[ecx+eax+4], 4
; Line 51
    mov ecx, 8
    imul    edx, ecx, 0
    mov eax, 1
    imul    ecx, eax, 0
    mov BYTE PTR _reg_matrix[edx+ecx], 18   ; 00000012H
; Line 52
    mov edx, 8
    imul    eax, edx, 0
    mov ecx, 1
    shl ecx, 0
    mov BYTE PTR _reg_matrix[eax+ecx], 52   ; 00000034H
; Line 53
    mov edx, 8
    imul    eax, edx, 0
    mov ecx, 1
    shl ecx, 1
    mov BYTE PTR _reg_matrix[eax+ecx], 86   ; 00000056H
; Line 54
    mov edx, 8
    imul    eax, edx, 0
    mov ecx, 1
    imul    edx, ecx, 3
    mov BYTE PTR _reg_matrix[eax+edx], 120  ; 00000078H
; Line 55
    mov eax, 8
    imul    ecx, eax, 0
    mov edx, 1
    shl edx, 2
    mov BYTE PTR _reg_matrix[ecx+edx], 1
; Line 56
    mov eax, 8
    imul    ecx, eax, 0
    mov edx, 1
    imul    eax, edx, 5
    mov BYTE PTR _reg_matrix[ecx+eax], 2
; Line 57
    mov ecx, 8
    imul    edx, ecx, 0
    mov eax, 1
    imul    ecx, eax, 6
    mov BYTE PTR _reg_matrix[edx+ecx], 3
; Line 58
    mov edx, 8
    imul    eax, edx, 0
    mov ecx, 1
    imul    edx, ecx, 7
    mov BYTE PTR _reg_matrix[eax+edx], 4
; Line 59
    pop ebp
    ret 0
_reg_init ENDP
_TEXT   ENDS
; Function compile flags: /Odtp
;   COMDAT _printf
_TEXT   SEGMENT
__Result$ = -8                      ; size = 4
__ArgList$ = -4                     ; size = 4
__Format$ = 8                       ; size = 4
_printf PROC                        ; COMDAT
; File C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt\stdio.h
; Line 954
    push    ebp
    mov ebp, esp
    sub esp, 8
; Line 957
    lea eax, DWORD PTR __Format$[ebp+4]
    mov DWORD PTR __ArgList$[ebp], eax
; Line 958
    mov ecx, DWORD PTR __ArgList$[ebp]
    push    ecx
    push    0
    mov edx, DWORD PTR __Format$[ebp]
    push    edx
    push    1
    call    ___acrt_iob_func
    add esp, 4
    push    eax
    call    __vfprintf_l
    add esp, 16                 ; 00000010H
    mov DWORD PTR __Result$[ebp], eax
; Line 959
    mov DWORD PTR __ArgList$[ebp], 0
; Line 960
    mov eax, DWORD PTR __Result$[ebp]
; Line 961
    mov esp, ebp
    pop ebp
    ret 0
_printf ENDP
_TEXT   ENDS
; Function compile flags: /Odtp
;   COMDAT __vfprintf_l
_TEXT   SEGMENT
__Stream$ = 8                       ; size = 4
__Format$ = 12                      ; size = 4
__Locale$ = 16                      ; size = 4
__ArgList$ = 20                     ; size = 4
__vfprintf_l PROC                   ; COMDAT
; File C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt\stdio.h
; Line 642
    push    ebp
    mov ebp, esp
; Line 643
    mov eax, DWORD PTR __ArgList$[ebp]
    push    eax
    mov ecx, DWORD PTR __Locale$[ebp]
    push    ecx
    mov edx, DWORD PTR __Format$[ebp]
    push    edx
    mov eax, DWORD PTR __Stream$[ebp]
    push    eax
    call    ___local_stdio_printf_options
    mov ecx, DWORD PTR [eax+4]
    push    ecx
    mov edx, DWORD PTR [eax]
    push    edx
    call    ___stdio_common_vfprintf
    add esp, 24                 ; 00000018H
; Line 644
    pop ebp
    ret 0
__vfprintf_l ENDP
_TEXT   ENDS
; Function compile flags: /Odtp
;   COMDAT ___local_stdio_printf_options
_TEXT   SEGMENT
___local_stdio_printf_options PROC          ; COMDAT
; File C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt\corecrt_stdio_config.h
; Line 86
    push    ebp
    mov ebp, esp
; Line 88
    mov eax, OFFSET ?_OptionsStorage@?1??__local_stdio_printf_options@@9@9 ; `__local_stdio_printf_options'::`2'::_OptionsStorage
; Line 89
    pop ebp
    ret 0
___local_stdio_printf_options ENDP
_TEXT   ENDS
END