Hãy xem xét các chương trình sau đây:Trình biên dịch có được phép tối ưu hóa việc sử dụng bộ nhớ ngăn xếp bằng cách sắp xếp lại các biến cục bộ không?
#include <stdio.h>
void some_func(char*, int*, char*);
void stack_alignment(void) {
char a = '-';
int i = 1337;
char b = '+';
some_func(&a, &i, &b); // to prevent the compiler from removing the local variables
printf("%c|%i|%c", a, i, b);
}
Nó tạo ra lắp ráp sau (thêm nhận xét của bản thân mình, tôi là một newbie hoàn toàn để lắp ráp):
$ vim stack-alignment.c
$ gcc -c -S -O3 stack-alignment.c
$ cat stack-alignment.s
.file "stack-alignment.c"
.section .rdata,"dr"
LC0:
.ascii "%c|%i|%c\0"
.text
.p2align 2,,3
.globl _stack_alignment
.def _stack_alignment; .scl 2; .type 32; .endef
_stack_alignment:
LFB7:
.cfi_startproc
subl $44, %esp
.cfi_def_cfa_offset 48
movb $45, 26(%esp) // local variable 'a'
movl $1337, 28(%esp) // local variable 'i'
movb $43, 27(%esp) // local variable 'b'
leal 27(%esp), %eax
movl %eax, 8(%esp)
leal 28(%esp), %eax
movl %eax, 4(%esp)
leal 26(%esp), %eax
movl %eax, (%esp)
call _some_func
movsbl 27(%esp), %eax
movl %eax, 12(%esp)
movl 28(%esp), %eax
movl %eax, 8(%esp)
movsbl 26(%esp), %eax
movl %eax, 4(%esp)
movl $LC0, (%esp)
call _printf
addl $44, %esp
.cfi_def_cfa_offset 4
ret
.cfi_endproc
LFE7:
.def _some_func; .scl 2; .type 32; .endef
.def _printf; .scl 2; .type 32; .endef
Như bạn thấy có 3 địa phương biến số (a
, i
và b
) với kích thước 1 byte, 4 byte và 1 byte. Bao gồm padding này sẽ là 12 byte (giả sử trình biên dịch căn chỉnh đến 4 byte).
Sẽ không hiệu quả hơn nếu trình biên dịch thay đổi thứ tự của các biến thành (a
, b
, i
)? Sau đó, chỉ cần 8 byte là cần thiết.
Dưới đây là một "đồ họa" đại diện:
3 bytes unused 3 bytes unused
vvvvvvvvvvv vvvvvvvvvvv
+---+---+---+---+---+---+---+---+---+---+---+---+
| a | | | | i | b | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
|
v
+---+---+---+---+---+---+---+---+
| a | b | | | i |
+---+---+---+---+---+---+---+---+
^^^^^^^
2 bytes unused
là trình biên dịch cho phép để làm tối ưu hóa này (theo tiêu chuẩn, vv C)?
- Nếu không (như tôi nghĩ đầu ra lắp ráp hiển thị), tại sao?
- Nếu có, tại sao điều đó không xảy ra ở trên?
Giả sử nó được cho phép theo các tiêu chuẩn, vv, thì nó sẽ hoàn toàn phụ thuộc vào việc thực thi trình biên dịch riêng lẻ cho dù chúng có thực hiện hay không. Tôi tưởng tượng nó sẽ được kiểm soát bởi các mức tối ưu hóa tại thời gian biên dịch. – John3136
Trình biên dịch/trình tối ưu hóa là miễn phí để đặt người dân địa phương ở bất cứ nơi nào họ muốn, miễn là nó không phá vỡ chương trình. Hoàn toàn miễn phí để đặt hai biến trong cùng một vị trí nếu chắc chắn chúng không bao giờ được sử dụng cùng một lúc. – mah
Bạn đã cố gắng biên dịch với các tùy chọn tối ưu hóa khác nhau chưa? Có lẽ bạn đã biên dịch với tối ưu hóa tắt. –