Tôi đang viết trình biên dịch cho một khóa học. Tôi đã chạy vào một số vấn đề tối ưu hóa mà tôi không chắc chắn cách xử lý tối ưu. Giả sử có một vòng lặp while từ ngôn ngữ đầu vào sử dụng N biến cục bộ phải được giữ trong sổ đăng ký (hoặc nên, để tính toán nhanh). Giả sử N> K, số lượng thanh ghi. Có một cơ hội của thanh ghi có điều kiện được thay đổi gần cuối vòng lặp while.Tạo mã trình biên dịch - đăng ký cấp phát bên trong các khối điều kiện
Ví dụ, giả sử thanh ghi cho x (giả sử% eax trên i386) được xác định trước tuyên bố sau:
while (x) { x = x - 1 ; /* more statements */ }
Trong báo cáo mã nhiều hơn, nó có thể cho x được đổ trở lại ngăn xếp. Khi mã nhảy trở lại phần đầu của vòng lặp while để đánh giá lại x, nó sẽ cố gắng sử dụng% eax - nhưng điều này có thể thậm chí không giữ giá trị của x bây giờ. Vì vậy, chúng ta có thể có cái gì đó như
movl -8(%ebp), %eax # eax <- x
.... # do stuff but let x stay in %eax
_LOOP1: cmpl $0, %eax
....
movl -12(%ebp), %eax #eax now holds something else
....
jmp _LOOP1
Một giải pháp tôi đang sử dụng là để buộc các mã để đổ tất cả các thanh ghi sửa đổi trước khi câu lệnh while (vì vậy thanh ghi này được xem như trống từ góc độ tạo mã của). Sau nhãn cho vòng lặp while, mã phải tải mọi thứ vào thanh ghi khi cần thiết.
Giải pháp của tôi là một cái gì đó như thế này:
movl -8(%ebp), %eax # eax <- x
.... # do stuff but let x stay in %eax
movl %eax, -8(%ebp) # spilling and clearing all registers
_LOOP1: movl -8(%ebp), %eax # get a register for x again
cmpl $0, %eax
....
movl -12(%ebp), %eax # eax now holds something else
....
movl %eax, -8(%ebp) # spill to prevent overwrite
jmp _LOOP1
Nó có vẻ như giải pháp của tôi là một chút không liên quan hoặc không cần thiết. Có một số mẹo tối ưu hóa chung tôi đang quên ở đây?
EDIT: Tôi cũng muốn lưu ý điều gì đó tương tự xảy ra cho các điều kiện như nếu và nếu có. Điều này xảy ra cho họ bởi vì một thanh ghi có thể được cấp phát cho một biến bên trong khối cho điều kiện, nhưng trình tạo mã giả định nó đã được chuyển vào đó cho mọi thứ khác sau đó. Tôi có cách tiếp cận tương tự để đối phó với trường hợp đó.
Tôi chưa có nhiều thời gian để xem xét điều này, nhưng có vẻ như có hiệu suất rất tối thiểu với chi phí phức tạp hơn? – Kizaru
Mức tăng được thay đổi tùy thuộc vào mã được biên dịch (như với tất cả các tối ưu hóa trình biên dịch). Rất ít tối ưu hóa ảnh hưởng đến tốc độ mã nhiều hơn một vài phần trăm tổng thể. –
Cảm ơn. Tôi đã nhận được tiền thưởng. Tôi muốn làm điều đó khi tôi đăng bình luận đầu tiên của mình. Sau một số trường hợp thử nghiệm, tối ưu hóa thực sự là tối thiểu (đối với i386). Tôi hy vọng nó sẽ hữu ích trên một kiến trúc như MIPS. – Kizaru