Câu hỏi này đã có câu trả lời ở đây:
Vì hệ thống 32 bit không thể quản lý số 2 ^ 33 (vì giới hạn 32 bit rõ ràng), làm thế nào có thể quản lý Điểm nổi 80 bit con số?
Nó cần "80-bit" ...
Câu hỏi này đã có câu trả lời ở đây:
Vì hệ thống 32 bit không thể quản lý số 2 ^ 33 (vì giới hạn 32 bit rõ ràng), làm thế nào có thể quản lý Điểm nổi 80 bit con số?
Nó cần "80-bit" ...
Câu trả lời:
Một trong những ý nghĩa của CPU 32 bit là các thanh ghi của nó rộng 32 bit. Điều này không có nghĩa là nó không thể đối phó với các số 64 bit, chỉ là nó phải xử lý nửa dưới 32 bit trước, sau đó là 32 bit trên nửa giây. (Đó là lý do tại sao CPU có một mang cờ .) Nó chậm hơn nếu CPU chỉ có thể tải các giá trị trong một thanh ghi 64 bit rộng hơn, nhưng vẫn có thể.
Do đó, "độ bit" của hệ thống không nhất thiết giới hạn kích thước của các số mà chương trình có thể xử lý, bởi vì bạn luôn có thể chia các hoạt động không phù hợp với các thanh ghi CPU thành nhiều hoạt động. Vì vậy, nó làm cho các hoạt động chậm hơn, tiêu thụ nhiều bộ nhớ hơn (nếu bạn phải sử dụng bộ nhớ làm "Scratchpad") và khó lập trình hơn, nhưng các thao tác vẫn có thể.
Tuy nhiên, không có vấn đề nào, ví dụ, bộ xử lý Intel 32 bit và dấu phẩy động, vì phần dấu phẩy động của CPU có các thanh ghi riêng và chúng có chiều rộng 80 bit. (Đầu tiên trong lịch sử của x86, khả năng dấu phẩy động là một con chip riêng biệt, nó được tích hợp trong CPU bắt đầu với 80486DX.)
Câu trả lời của Đột phá đã truyền cảm hứng cho tôi để thêm điều này.
Các giá trị dấu phẩy động, trong khi chúng được lưu trữ trong các thanh ghi FPU, hoạt động rất khác so với các giá trị nguyên nhị phân.
80 bit của một giá trị dấu phẩy động được chia cho một số mũ và số mũ (cũng có "cơ sở" trong các số dấu phẩy động luôn luôn là 2). Lớp phủ chứa các chữ số có nghĩa và số mũ xác định các chữ số có nghĩa đó lớn đến mức nào. Vì vậy, không có "tràn" vào một thanh ghi khác, nếu số của bạn quá lớn để phù hợp với lớp phủ, số mũ của bạn tăng và bạn mất độ chính xác - tức là khi bạn chuyển đổi nó thành một số nguyên, bạn sẽ mất số thập phân bên phải - đây là lý do tại sao nó được gọi là điểm nổi.
Nếu số mũ của bạn quá lớn, thì bạn có tràn điểm nổi, nhưng bạn không thể dễ dàng mở rộng nó sang một thanh ghi khác vì số mũ và mantissa được gắn với nhau.
Tôi có thể không chính xác và sai về một số điều đó, nhưng tôi tin rằng đó là ý chính của nó. (Điều này Bài viết trên Wikipedia minh họa ở trên một chút ngắn gọn hơn.)
Không sao, điều này hoạt động hoàn toàn khác vì toàn bộ phần "điểm nổi" của CPU thuộc loại trong thế giới riêng của nó - bạn sử dụng các hướng dẫn CPU đặc biệt để truy cập vào nó và như vậy. Ngoài ra, về phía câu hỏi, bởi vì nó tách biệt, độ bit của FPU không được kết hợp chặt chẽ với bitness của CPU gốc.
-fomit-frame-pointer
để có được đăng ký trở lại.
Tất cả 32 bit, 64 bit và 128 bit đều đề cập đến độ dài từ của bộ xử lý, có thể được coi là "kiểu dữ liệu cơ bản". Thông thường, đây là số bit được truyền đến / từ RAM của hệ thống và độ rộng của con trỏ (mặc dù không có gì ngăn bạn sử dụng phần mềm để truy cập thêm RAM, sau đó một con trỏ có thể truy cập).
Giả sử tốc độ đồng hồ không đổi (cũng như mọi thứ khác trong kiến trúc là không đổi) và giả sử bộ nhớ đọc / ghi là cùng tốc độ (chúng tôi giả sử 1 chu kỳ đồng hồ ở đây, nhưng điều này khác xa với thực tế thêm hai số 64 bit trong một chu kỳ xung nhịp đơn trên máy 64 bit (ba nếu bạn đếm tìm nạp các số từ RAM):
ADDA [NUM1], [NUM2]
STAA [RESULT]
Chúng tôi cũng có thể làm tính toán tương tự trên máy 32 bit ... Tuy nhiên, trên máy 32 bit, chúng ta cần thực hiện điều này trong phần mềm, vì trước tiên phải thêm 32 bit, bù cho tràn, sau đó thêm 64 bit trên:
ADDA [NUM1_LOWER], [NUM2_LOWER]
STAA [RESULT_LOWER]
CLRA ; I'm assuming the condition flags are not modified by this.
BRNO CMPS ; Branch to CMPS if there was no overflow.
ADDA #1 ; If there was overflow, compensate the value of A.
CMPS ADDA [NUM1_UPPER], [NUM2_UPPER]
STAA [RESULT_UPPER]
Xem qua cú pháp lắp ráp hoàn chỉnh của tôi, bạn có thể dễ dàng thấy các thao tác có độ chính xác cao hơn có thể mất thời gian lâu hơn theo cấp số nhân trên một máy có độ dài từ thấp hơn. Đây là chìa khóa thực sự cho bộ xử lý 64 bit và 128 bit: chúng cho phép chúng tôi xử lý số lượng bit lớn hơn trong một hoạt động. Một số máy bao gồm các hướng dẫn để thêm số lượng khác mang theo (ví dụ: ADC
trên x86), nhưng ví dụ trên có các giá trị chính xác tùy ý.
Bây giờ, để mở rộng câu hỏi này, thật đơn giản để xem làm thế nào chúng ta có thể thêm các số lớn hơn các thanh ghi mà chúng ta có sẵn - chúng ta chỉ chia vấn đề thành các phần của kích thước các thanh ghi và làm việc từ đó. Mặc dù như đã đề cập bởi @MatteoItalia , ngăn xếp x87 FPU có hỗ trợ riêng cho số lượng 80 bit, trong các hệ thống thiếu hỗ trợ này (hoặc bộ xử lý thiếu đơn vị điểm nổi hoàn toàn!), phải thực hiện tính toán / thao tác tương đương trong phần mềm .
Vì vậy, đối với số 80 bit, sau khi thêm từng phân đoạn 32 bit, người ta cũng sẽ kiểm tra xem có bị tràn vào bit 81 bit hay không và tùy chọn không đưa ra các bit thứ tự cao hơn. Các kiểm tra / số không này được thực hiện tự động cho một số lệnh x86 và x86-64 nhất định, trong đó kích thước toán hạng nguồn và đích được chỉ định (mặc dù các kích thước này chỉ được chỉ định trong các mức 2 bắt đầu từ rộng 1 byte).
Tất nhiên, với các số dấu phẩy động, người ta không thể thực hiện phép cộng nhị phân một cách đơn giản vì phần tử và các chữ số có nghĩa được đóng gói cùng nhau ở dạng bù. Trong ALU trên bộ xử lý x86, có một mạch phần cứng để thực hiện điều này cho các phao nổi 32 bit và 64 bit của IEEE; Tuy nhiên , ngay cả khi không có đơn vị dấu phẩy động (FPU), các phép tính tương tự có thể được thực hiện trong phần mềm (ví dụ: thông qua việc sử dụng Thư viện khoa học GNU , sử dụng một FPU khi được biên dịch trên các kiến trúc, quay lại thuật toán phần mềm nếu không có phần cứng dấu phẩy động nào [ví dụ: đối với các vi điều khiển nhúng thiếu FPU]).
Cho đủ bộ nhớ, người ta cũng có thể thực hiện tính toán trên các số tùy ý (hoặc "vô hạn" - trong giới hạn thực tế), sử dụng nhiều bộ nhớ hơn vì cần độ chính xác cao hơn. Một thực hiện này tồn tại trong GNU Nhiều thư viện chính xác , cho phép độ chính xác không giới hạn (tất nhiên cho đến khi RAM của bạn đầy) trên các hoạt động số nguyên, hợp lý và dấu phẩy động.
Kiến trúc bộ nhớ của hệ thống chỉ có thể cho phép bạn di chuyển 32 bit cùng một lúc - nhưng điều đó không ngăn nó sử dụng số lớn hơn.
Hãy nghĩ về phép nhân. Bạn có thể biết các bảng nhân của mình lên tới 10 x 10, nhưng có lẽ bạn không gặp vấn đề gì khi thực hiện 123x321 trên một tờ giấy: bạn chỉ chia nó thành nhiều vấn đề nhỏ, nhân các chữ số riêng lẻ và chăm sóc v.v.
Bộ xử lý có thể làm điều tương tự. Trong "thời xa xưa", bạn có bộ xử lý 8 bit có thể thực hiện phép toán dấu phẩy động. Nhưng họ đã rất chậm.
"32-bit" thực sự là một cách phân loại bộ xử lý, không phải là phán quyết chính thức. bộ xử lý "32 bit" thường có các thanh ghi mục đích chung 32 bit để làm việc.
Tuy nhiên, không có yêu cầu nào được đặt ra rằng mọi thứ trong bộ xử lý phải được thực hiện trong 32 bit. Ví dụ, không có gì lạ khi máy tính "32 bit" có bus địa chỉ 28 bit, vì nó rẻ hơn để làm phần cứng. Máy tính 64 bit thường chỉ có bus bộ nhớ 40 bit hoặc 48 bit vì lý do tương tự.
Số học dấu phẩy động là một nơi khác có kích thước khác nhau. Nhiều bộ xử lý 32 bit hỗ trợ số dấu phẩy động 64 bit. Họ đã làm như vậy bằng cách lưu trữ các giá trị dấu phẩy động trong các thanh ghi đặc biệt rộng hơn các thanh ghi mục đích chung. Để lưu trữ một trong những số dấu phẩy động lớn này trong các thanh ghi đặc biệt, trước tiên người ta sẽ chia số đó cho hai thanh ghi mục đích chung, sau đó đưa ra một hướng dẫn để kết hợp chúng thành một dấu phẩy trong các thanh ghi đặc biệt. Khi đã ở trong các thanh ghi dấu phẩy động đó, các giá trị sẽ được xử lý dưới dạng các phao 64 bit, thay vì một nửa các nửa 32 bit.
Số học 80 bit mà bạn đề cập là một trường hợp đặc biệt của điều này. Nếu bạn đã làm việc với các số dấu phẩy động, bạn sẽ quen với sự thiếu chính xác phát sinh từ các vấn đề làm tròn điểm nổi. Một giải pháp cho việc làm tròn là có nhiều bit chính xác hơn, nhưng sau đó bạn phải lưu trữ số lượng lớn hơn và buộc các nhà phát triển sử dụng các giá trị dấu phẩy động lớn bất thường trong bộ nhớ.
Giải pháp của Intel là các thanh ghi dấu phẩy động có tất cả 80 bit, nhưng các hướng dẫn để di chuyển các giá trị đến / từ các thanh ghi đó hoạt động chủ yếu với các số 64 bit. Miễn là bạn hoạt động hoàn toàn trong ngăn xếp dấu phẩy động x87 của Intel, tất cả các hoạt động của bạn đều được thực hiện với độ chính xác 80 bit. Nếu mã của bạn cần kéo một trong các giá trị đó ra khỏi các thanh ghi dấu phẩy động và lưu trữ nó ở đâu đó, nó sẽ cắt nó thành 64 bit.
Đạo đức của câu chuyện: các phân loại như "32-bit" luôn nguy hiểm hơn khi bạn hiểu sâu hơn về mọi thứ!
CPU "32 bit" là một trong đó hầu hết các thanh ghi dữ liệu là các thanh ghi 32 bit và hầu hết các lệnh hoạt động trên dữ liệu trong các thanh ghi 32 bit đó. CPU 32 bit cũng có khả năng truyền dữ liệu đến và từ bộ nhớ 32 bit mỗi lần. Hầu hết các thanh ghi là 32 bit không có nghĩa là tất cả các thanh ghi là 32 bit. Câu trả lời ngắn gọn là CPU 32 bit có thể có một số tính năng sử dụng các bitcount khác, chẳng hạn như các thanh ghi dấu phẩy động 80 bit và các hướng dẫn tương ứng.
Như @spudone đã nói trong một nhận xét về câu trả lời của @ ultrasawblade, CPU x86 đầu tiên được tích hợp các hoạt động điểm nổi là Intel i486 (cụ thể là 80486DX nhưng không phải là 80486SX), theo Trang 15-1 của Tài liệu tham khảo Lập trình viên vi xử lý i486 , bao gồm trong các thanh ghi số "Tám thanh ghi số 80 bit có thể định địa chỉ riêng lẻ". I486 có bus bộ nhớ 32 bit, do đó, việc chuyển giá trị 80 bit sẽ mất 3 thao tác bộ nhớ.
Tiền thân của thế hệ 486, i386, không có bất kỳ hoạt động điểm nổi tích hợp nào. Thay vào đó, nó có hỗ trợ cho việc sử dụng "bộ đồng xử lý" dấu phẩy động bên ngoài, 80387. Bộ đồng xử lý này có chức năng gần như được tích hợp vào i486, như bạn có thể thấy từ Trang 2-1 của Tài liệu tham khảo dành cho lập trình viên 80387 .
Định dạng dấu phẩy động 80 bit dường như bắt nguồn từ 8087, bộ đồng xử lý toán học cho 8086 và 8088. 8086 và 8088 là CPU 16 bit (với bus bộ nhớ 16 bit và 8 bit), và vẫn có thể để sử dụng định dạng dấu phẩy động 80 bit, bằng cách tận dụng các thanh ghi 80 bit trong bộ đồng xử lý.