có thể là bất kỳ hình phạt khi trộn 32 và kích thước đăng ký 64-bit trong hướng dẫn liên tiếp?
No, writing to a 32-bit register always zero-extends to the full register, vì vậy x86-64 tránh mọi hình phạt đăng ký một phần cho lệnh 32 và 64 bit.
vì vậy tôi tin rằng 32 bit vẫn là nguồn gốc.
Có, kích thước mặc định là 32 bit cho hầu hết các hướng dẫn (other than PUSH/POP). 64-bit cần tiền tố REX với bit W được đặt thành 1. Vì vậy, thích 32-bit vì lý do kích thước mã. Đây là lý do tại sao trình biên dịch sử dụng mov r32, imm32
cho địa chỉ của dữ liệu tĩnh (vì mô hình mã mặc định yêu cầu mã và địa chỉ dữ liệu tĩnh nằm trong 2GiB thấp của không gian địa chỉ ảo).
Đó là một lựa chọn thiết kế của AMD. Họ có thể đã chọn cách khác, và yêu cầu một tiền tố để có được kích thước toán hạng 32 bit. Vì chế độ dài là một chế độ riêng biệt, mã máy x86-64 có thể khác với mã máy x86-32 nhưng nó muốn. AMD đã chọn để giảm thiểu sự khác biệt để họ có thể chia sẻ càng nhiều bóng bán dẫn càng tốt trong bộ giải mã. Kết luận của bạn là chính xác, nhưng lý do của bạn là hoàn toàn không có thật.
cập nhật đăng ký từng phần (như rìu thay vì eax) có thể gây ra gian hàng eflags và suy giảm hiệu suất.
Quầy cờ một phần riêng biệt với các quầy đăng ký một phần. Chúng được xử lý tương tự trong nội bộ (các phần được đổi tên riêng của EFLAGS phải được hợp nhất giống như một AX đã sửa đổi phải được hợp nhất với các byte trên chưa sửa đổi của EAX). Nhưng một không gây ra khác.
# partial-reg stall
setcc al # leaves the upper 3 (or 7) bytes unmodified
add edx, eax # reads full EAX. Older CPUs stall while merging
Zeroing EAX ahead of the flag-setting and setcc with xor eax,eax
avoids the partial-register penalty entirely. (Core2/Nehalem quầy hàng cho chu kỳ ít hơn so với CPU trước đó, nhưng vẫn còn gian hàng cho 2 hoặc 3c trong khi chèn một uop sáp nhập.Sandybridge không dừng lại ở tất cả trong khi chèn uop sáp nhập).
(Một bản tóm tắt các hình phạt đăng ký một phần trên các CPU khác nhau: Why doesn't GCC use partial registers?, nói về cơ bản giống nhau).
AMD không bị các quầy đăng ký từng phần khi đọc toàn bộ sổ đăng ký sau đó, nhưng thay vào đó ghi một phần ghi và đọc có phụ thuộc sai trên thanh ghi đầy đủ. (CPU AMD không đổi tên riêng các sổ đăng ký phụ ở vị trí đầu tiên. Intel P4 và Silvermont/Knight's Landing cũng giống như vậy.)
Intel Haswell/Skylake (và có thể Ivybridge) không đổi tên al
riêng biệt rax
tại tất cả, vì vậy chúng không bao giờ cần hợp nhất các thanh ghi low8/low16. Nhưng setcc al
có sự phụ thuộc sai về giá trị cũ. Họ vẫn đổi tên và hợp nhất ah
. (Details on HSW/SKL partial-reg performance.)
# partial flag stall when reading a flag that didn't come from
# the last instruction to write any flags.
clc
# edi and esi = one-past-the-end of dst and src
# ecx = -count
bigInt_add:
mov eax, [esi+ecx*4]
adc [edi+ecx*4], eax # reads CF, partial flag stall on 2nd and later iterations
inc ecx # writes all flags except CF
jl bitInt_add # loop upwards towards zero
Xem this Q&A để thảo luận thêm về phần-cờ vấn đề về Intel trước Sandybridge vs Sandybridge.
Xem thêm Agner Fog's microarch pdf, và các liên kết khác trong x86 thẻ wiki để biết thêm chi tiết về tất cả điều này.
Có các hình phạt cho quyền truy cập 16 bit. Sử dụng thanh ghi 32 bit và tránh r8-r15 là OK và trên thực tế thường dẫn đến kích thước mã nhỏ hơn. –
Việc ghi vào thanh ghi 32 bit sẽ tự động xóa 32 bit trên cùng, do đó tránh được vấn đề cập nhật từng phần. – Jester
Đăng ký EFLAGS được ảo hóa rất nhiều trong các bộ vi xử lý hiện đại. Giống như tất cả các thanh ghi. Nhất thiết như vậy, quá nhiều hướng dẫn sửa đổi nó và đó là một damper lớn về thực hiện siêu vô hướng. Những gì còn thiếu trong mã của bạn là một lệnh thực sự * sử dụng * thanh ghi. Vì vậy, không có lý do thuyết phục nào để bộ xử lý khóa và khóa mã bạn đăng. Không bao giờ lấy ý kiến của ai đó về cách nó nên/có thể làm việc. Điểm duy nhất để viết mã assembly là làm cho nó nhanh hơn trình biên dịch C. Đo. –