Một số CPU có đăng ký cờ (ARM, x86, ...), số khác thì không (MIPS, ...). Lợi thế của việc có một lệnh CMP để cập nhật thanh ghi cờ theo sau là lệnh rẽ nhánh thay vì sử dụng thanh ghi 0 và các nhánh có điều kiện để kiểm tra ký, tràn vv?
Một số CPU có đăng ký cờ (ARM, x86, ...), số khác thì không (MIPS, ...). Lợi thế của việc có một lệnh CMP để cập nhật thanh ghi cờ theo sau là lệnh rẽ nhánh thay vì sử dụng thanh ghi 0 và các nhánh có điều kiện để kiểm tra ký, tràn vv?
Câu trả lời:
Trong các kiến trúc vi mô hiện đại với đăng ký đổi tên chi phí thực hiện cho các cờ hoặc không cờ là khá giống nhau. Sự khác biệt chính mà tôi có thể nghĩ đến là một số cờ biểu thị các đặc điểm của một giá trị (Giá trị này có bị âm không? Giá trị có bằng 0 không? Giá trị này có chẵn lẻ hay lẻ không?), Trong khi một số biểu thị một sự kiện xảy ra trong một hoạt động trước đó (hướng dẫn thêm có thực hiện hoặc tràn không?) Điều này dẫn đến một tình huống không lý tưởng trên MIPS khi bạn muốn mô phỏng bổ sung 64 bit trên kiến trúc 32 bit (hoặc bổ sung 128 bit trên Kiến trúc 64 bit.) Trên hầu hết các kiến trúc có cờ mang có một đặc biệtadd-with-carry
hướng dẫn, bao gồm cờ thực hiện từ hướng dẫn thêm trước đó. Điều này làm cho việc mô phỏng số học đa độ chính xác tương đối rẻ tiền trên nhiều kiến trúc với các thanh ghi cờ.
Mặt khác, việc kiểm tra một thanh ghi N-bit cho 0 hoặc không-0 thực sự tốn kém đáng ngạc nhiên. Để kiểm tra thanh ghi N-bit bằng 0, bạn cần thực hiện thao tác N-bit NOR, yêu cầu mức logic để tính toán. Trên các kiến trúc có cờ đăng ký logic bổ sung cho phép tính 0 / không bằng 0 ở cuối giai đoạn ALU có thể khiến đồng hồ chạy chậm hơn (hoặc buộc ALU phải có hai hoạt động theo chu kỳ.) Vì lý do này, tôi nghĩ, một số Các kiến trúc, như SPARC có hai phiên bản của mỗi phép toán số học, một phiên bản đặt cờ và một phiên bản không.
Nhưng MIPS không lưu bất cứ thứ gì ở đây. Họ chỉ di chuyển vấn đề ở một nơi khác. Trên MIPS có branch-on-equal
hướng dẫn. Điều này có nghĩa là lệnh rẽ nhánh thực sự phải có giai đoạn ALU (bao gồm cả thao xor
tác bitwise theo sau là nor
giảm xuống một bit bằng / không bằng nhau) trước khi xác định đường nhánh đi.
Kiến trúc DEC Alpha đã cố gắng phân chia sự khác biệt bằng cách sử dụng một mẹo. DEC Alpha không có đăng ký cờ, nhưng cũng không có branch-on-equal
hướng dẫn. Thay vào đó, tất cả các hướng dẫn chi nhánh nhìn vào trạng thái của một thanh ghi mục đích chung duy nhất. Có branch-on-zero
, branch-on-not-zero
, branch-on-less-than-zero
vv Bí quyết là bạn có thể cung cấp cho mỗi mục đích chung đăng ký một chút 65 bổ sung mà cho bạn biết liệu 64 bit khác đều không hay không. Điều này làm cho nó giống như có một thanh ghi cờ: tất cả các hướng dẫn chi nhánh đều nhìn vào một bit (đã được tính toán) để đưa ra quyết định của chúng, nhưng bây giờ bạn đã quay lại để tìm ra cách tính bit chỉ số 0 bổ sung đó trong ALU bình thường đi xe đạp. (Và bạn vẫn không thể thực hiện số học đa chính xác chỉ bằng cách nhìn vào cờ mang từ hoạt động trước đó.)
Có các hướng dẫn kiểm tra chỉ thiết lập các cờ chỉ là một cách để giảm áp lực đăng ký trong các kiến trúc bị bỏ đói đăng ký. Nếu bạn có đủ đăng ký, chỉ cần sửa đổi một trong số họ và bỏ qua kết quả. Thủ thuật để có một thanh ghi 0 với giá trị đầu vào 0 chỉ là một thủ thuật mã hóa thuận tiện khi bạn có đủ các thanh ghi mà sửa một trong số chúng thành 0 tốt hơn là tăng số lượng lệnh. Sau đó, nó cũng thuận tiện để sử dụng nó làm mục tiêu (nó làm giảm số lượng phụ thuộc sai).
Mã hóa lại. Nếu bạn mã hóa điều kiện trong các lần nhảy, bạn sẽ có các bước nhảy với 3 toán hạng (hai toán tử được so sánh và mục tiêu nhảy), hai trong số đó bạn muốn trở thành giá trị ngay lập tức, một trong số đó bạn muốn lớn như có thể (các bước nhảy thường có định dạng mã hóa riêng để mục tiêu có thể sử dụng càng nhiều bit càng tốt). Hoặc bạn bỏ khả năng.
Sử dụng cờ cho bạn nhiều cơ hội hơn để thiết lập chúng. Nó không chỉ là các hoạt động so sánh có thể đặt cờ, mà là bất cứ điều gì bạn muốn. (Với lời cảnh báo rằng bạn có càng nhiều thao tác đặt cờ, bạn càng phải cẩn thận hơn để đảm bảo rằng thao tác cuối cùng đặt cờ là thao tác bạn muốn). Nếu bạn có cờ, bạn có thể kiểm tra số điều kiện (thường là 16) nhân với số lượng hướng dẫn có thể đặt cờ (Nếu bạn không sử dụng cờ, bạn sẽ có nhiều lần nhảy có điều kiện như bạn có những thứ cần kiểm tra hoặc có những thứ bạn không cho phép kiểm tra một cách dễ dàng (ví dụ như mang hoặc tràn).
Cờ kiểm tra là dễ dàng và có thể được thực hiện nhanh chóng. Thử nghiệm của bạn càng phức tạp thì càng có nhiều ảnh hưởng đến thời gian chu kỳ (hoặc cấu trúc đường ống nếu bạn được đặt đường ống). Điều đó đặc biệt đúng đối với việc triển khai đơn giản hơn, khi bạn sử dụng bộ xử lý cao cấp bằng tất cả các thủ thuật của cuốn sách, hiệu quả là khá nhỏ.
Có cờ có nghĩa là rất nhiều hướng dẫn có nhiều kết quả (kết quả tự nhiên và mỗi cờ được sửa đổi). Và từ một POV kiến trúc vi mô, nhiều kết quả rất tệ (bạn phải theo dõi liên kết của chúng). Khi bạn chỉ có một bộ cờ, điều đó đưa ra các phụ thuộc (không cần thiết nếu cờ không được sử dụng), bạn phải xử lý cách này hay cách khác. Một lần nữa, điều đó đặc biệt đúng đối với việc triển khai đơn giản hơn, khi bạn đến một bộ xử lý cao cấp bằng cách sử dụng tất cả các thủ thuật của cuốn sách, những khó khăn khác sẽ bị các bộ xử lý còn lại lấn át.
Trên máy 32 bit, lệnh "add-with-carry" được sử dụng như một phần của chuỗi bổ sung đa độ chính xác cần chấp nhận toán hạng trị giá 65 bit và tính tổng 33 bit. Các đặc tả của thanh ghi nguồn sẽ xác định 64 bit toán hạng sẽ đến từ đâu và đặc tả của thanh ghi đích sẽ cho biết 32 bit thấp hơn của kết quả sẽ đi đâu, nhưng phải làm gì với toán hạng "thêm một" hoặc bit trên của kết quả? Được phép chỉ định như một phần của hướng dẫn nơi toán hạng bổ sung sẽ đến và nơi bit kết quả bổ sung sẽ hữu ích ở mức độ vừa phải, nhưng nói chung sẽ không hữu ích khi chứng minh một trường bổ sung trong opcode. Có một "vị trí" cố định để xử lý cờ mang có thể hơi khó xử từ góc độ lập lịch hướng dẫn, nhưng nó '
Nếu một người đang cố gắng thiết kế một tập lệnh để cho phép số học đa độ chính xác nhưng mỗi lệnh được giới hạn ở hai toán hạng 32 bit và một toán hạng đích 32 bit, thì người ta có thể thực hiện "thêm" 64 bit trong bốn lệnh: "set r5 đến 1 nếu r0 + r2 sẽ mang hoặc bằng không, tính toán r4 = r1 + r3; tính r5 = r4 + r5; tính r4 = r0 + r2 ", nhưng vượt quá điều đó sẽ yêu cầu ba hướng dẫn cho mỗi từ bổ sung. Có một cờ mang có sẵn như là một nguồn bổ sung và đích sẽ giảm chi phí cho một hướng dẫn cho mỗi từ.
Lưu ý, btw, rằng có một điều khiển bit lệnh cho dù lệnh có cập nhật thanh ghi cờ có thể tạo điều kiện cho việc thực hiện không theo thứ tự hay không, vì các lệnh sử dụng hoặc sửa đổi các bit cờ phải duy trì chuỗi của chúng so với nhau, nhưng các lệnh không thể được tự do sắp xếp lại. Đưa ra trình tự:
ldr r0,[r1]
add r0,r0,r2
eors r4,r5,r6
một đơn vị thực thi có thể dễ dàng nhận ra rằng lệnh thứ ba có thể thực thi mà không phải chờ dữ liệu được đọc từ đó [r1]
, nhưng nếu lệnh thứ hai là adds r0,r0,r2
điều đó chỉ có thể xảy ra nếu đơn vị thực thi có thể đảm bảo rằng đến lúc mọi thứ cố gắng sử dụng các cờ, cờ 0 sẽ giữ giá trị được thiết lập trong lệnh thứ ba nhưng cờ mang sẽ giữ giá trị trong giây.
Câu trả lời đơn giản ... thao tác bộ nhớ giá rẻ nhanh chóng mà hoàn toàn không yêu cầu sử dụng nội bộ ngoại trừ hướng dẫn. Nó có thể được sử dụng như một bool stack mà không có stack hoặc bit process, không có bộ nhớ.