Chỉ cần thêm một cái gì đó cho tùy chọn "ngôn ngữ khác".
C: Vì đây chỉ là một bài tập học thuật thực sự không có gì khác biệt, tôi nghĩ tôi sẽ đóng góp một cái gì đó khác biệt.
Tôi biên dịch để lắp ráp mà không tối ưu hóa và xem kết quả.
Mật mã:
int main() {
volatile int a;
volatile int b;
asm("## 5/2\n");
a = 5;
a = a / 2;
asm("## 5*0.5");
b = 5;
b = b * 0.5;
asm("## done");
return a + b;
}
biên dịch với gcc tdiv.c -O1 -o tdiv.s -S
chia cho 2:
movl $5, -4(%ebp)
movl -4(%ebp), %eax
movl %eax, %edx
shrl $31, %edx
addl %edx, %eax
sarl %eax
movl %eax, -4(%ebp)
và phép nhân với 0,5:
movl $5, -8(%ebp)
movl -8(%ebp), %eax
pushl %eax
fildl (%esp)
leal 4(%esp), %esp
fmuls LC0
fnstcw -10(%ebp)
movzwl -10(%ebp), %eax
orw $3072, %ax
movw %ax, -12(%ebp)
fldcw -12(%ebp)
fistpl -16(%ebp)
fldcw -10(%ebp)
movl -16(%ebp), %eax
movl %eax, -8(%ebp)
Tuy nhiên, khi tôi đổi những cái đó int
thành double
s (đó là điều mà con trăn có thể sẽ làm), tôi đã nhận được điều này:
bộ phận:
flds LC0
fstl -8(%ebp)
fldl -8(%ebp)
flds LC1
fmul %st, %st(1)
fxch %st(1)
fstpl -8(%ebp)
fxch %st(1)
phép nhân:
fstpl -16(%ebp)
fldl -16(%ebp)
fmulp %st, %st(1)
fstpl -16(%ebp)
Tôi đã không điểm chuẩn bất kỳ mã nào trong số này, nhưng chỉ bằng cách kiểm tra mã bạn có thể thấy rằng sử dụng số nguyên, phép chia cho 2 ngắn hơn nhân với 2. Sử dụng nhân đôi, phép nhân ngắn hơn vì trình biên dịch sử dụng mã op dấu phẩy động của bộ xử lý, có thể chạy nhanh hơn (nhưng thực ra tôi không biết) hơn là không sử dụng chúng cho cùng một hoạt động. Vì vậy, cuối cùng câu trả lời này đã chỉ ra rằng hiệu suất của phép nhân 0,5 so với chia cho 2 phụ thuộc vào việc triển khai ngôn ngữ và nền tảng mà nó chạy trên đó. Cuối cùng, sự khác biệt là không đáng kể và là điều bạn hầu như không bao giờ phải lo lắng, ngoại trừ về khả năng đọc.
Là một lưu ý phụ, bạn có thể thấy rằng trong chương trình của tôi main()
trở lại a + b
. Khi tôi mang từ khóa không ổn định đi, bạn sẽ không bao giờ đoán được phần lắp ráp trông như thế nào (không bao gồm cài đặt chương trình):
## 5/2
## 5*0.5
## done
movl $5, %eax
leave
ret
nó đã thực hiện cả phép chia, phép nhân và phép cộng trong một lệnh đơn! Rõ ràng bạn không phải lo lắng về điều này nếu trình tối ưu hóa là bất kỳ loại đáng kính nào.
Xin lỗi vì câu trả lời quá dài.