Sự khác biệt giữa số dấu phẩy động cứng và mềm là gì?


98

Khi tôi biên dịch mã C với chuỗi công cụ chéo của mình, trình liên kết in ra các trang cảnh báo nói rằng tệp thực thi của tôi sử dụng phao cứng nhưng libc của tôi sử dụng phao mềm. Có gì khác biệt?


Nếu đó là kiến trúc ARM xin vui lòng đặt đó vào thẻ :-)
Nils Pipenbrinck

3
@Nils Pipenbrinck: MIPS chip cũng có vấn đề này
Javier

Câu trả lời:


100

Phao cứng sử dụng đơn vị dấu phẩy động trên chip. Các phao mềm giả lập một trong phần mềm. Sự khác biệt là tốc độ. Thật kỳ lạ khi cả hai được sử dụng trên cùng một kiến ​​trúc mục tiêu, vì chip có FPU hoặc không. Bạn có thể bật dấu phẩy động mềm trong GCC với -msoft-float. Bạn có thể muốn biên dịch lại libc của mình để sử dụng dấu phẩy động phần cứng nếu bạn sử dụng nó.


3
"Thật kỳ lạ khi thấy cả hai được sử dụng trên cùng một kiến ​​trúc đích" Điều này có thể có ý nghĩa đối với một thư viện độc lập với máy và chính xác theo bit (soft float) trong các phần quan trọng về độ chính xác và nhanh (hard float) trong các phần có độ lệch nhỏ không không quan trọng.
PhilLab

Nó xảy ra trên ARM 32-bit.
Aaron Franke

31

Có ba cách để tính số học dấu phẩy động:

  • Sử dụng hướng dẫn float nếu CPU của bạn có FPU. (Nhanh)
  • Yêu cầu trình biên dịch của bạn dịch số học dấu phẩy động sang số học số nguyên. (chậm)
  • Sử dụng hướng dẫn float và CPU không có FPU. CPU của bạn sẽ tạo ra một ngoại lệ (Lệnh dành riêng, Lệnh chưa thực hiện hoặc tương tự) và nếu hạt nhân hệ điều hành của bạn bao gồm trình giả lập dấu phẩy động, nó sẽ mô phỏng các lệnh đó (chậm nhất).

23

Nói một cách chính xác, tất cả những câu trả lời này dường như sai đối với tôi.

Khi tôi biên dịch mã C với chuỗi công cụ chéo của mình, trình liên kết in ra các trang cảnh báo nói rằng tệp thực thi của tôi sử dụng phao cứng nhưng libc của tôi sử dụng phao mềm. Có gì khác biệt?

Wiki VFP Debian có thông tin về ba lựa chọn cho -mfloat-abi,

  • soft - đây là phần mềm thuần túy
  • softfp- cái này hỗ trợ FPU phần cứng, nhưng ABI tương thích mềm.
  • hard- ABI sử dụng thanh ghi float hoặc VFP .

Lỗi trình liên kết (trình tải) là do bạn có một thư viện được chia sẻ sẽ chuyển các giá trị dấu phẩy động trong thanh ghi số nguyên. Bạn vẫn có thể biên dịch mã của mình với a -mfpu=vfp, v.v. nhưng bạn nên sử dụng -mfloat-abi=softfpđể nếu libc cần float, nó sẽ được truyền theo cách mà thư viện hiểu được.

Nhân Linux có thể hỗ trợ mô phỏng các lệnh VFP. Rõ ràng, bạn nên biên dịch với -mfpu=nonetrường hợp này và để trình biên dịch tạo mã trực tiếp thay vì dựa vào bất kỳ mô phỏng hạt nhân Linux nào. Tuy nhiên, tôi không tin rằng lỗi của OP thực sự liên quan đến vấn đề này. Nó là riêng biệt và cũng phải được xử lý cùng với -mfloat-abi.

Thư viện chia sẻ Armv5 với CPU ArmV7 là đối lập với thư viện này; các libc là phao cứng nhưng ứng dụng chỉ mềm . Nó có một số cách để giải quyết vấn đề, nhưng biên dịch lại với các tùy chọn chính xác luôn là cách dễ dàng nhất.

Một vấn đề khác là nhân Linux phải hỗ trợ các tác vụ VFP (hoặc bất kỳ dấu phẩy động nào của ARM) để lưu / khôi phục các thanh ghi trên một công tắc ngữ cảnh.


1
Phiên bản GCC hiện đại (~ 4.8 +) hỗ trợ 'multi-lib', có thư viện float cứng và float mềm. Các phiên bản trước yêu cầu bạn phải có một trình biên dịch được xây dựng với một phiên bản cụ thể. Đôi khi cần có đường dẫn đến đúng thư viện khi liên kết với bản phân phối gcc 'nhiều lib' vì có một số phiên bản thư viện (yêu cầu thời gian xây dựng trình biên dịch lâu hơn). Tên thư mục có thể là 'hf', 'hardf', 'libhf' hoặc 'hard-float' nhưng chúng thường nằm trong thư mục 'soft' thông thường hoặc một vị trí gần đó.
tiếng ồn không có nghệ thuật.

Đây là câu trả lời đúng. Việc chuyển đổi lệnh gọi cho float cần phải khớp giữa mã của bạn và libc. Nó có thể vẫn hoạt động với một hàm không khớp, nếu bạn không bao giờ gọi bất kỳ hàm libc dấu chấm động nào.
Tor Klingberg

13

Có vẻ như libc của bạn được xây dựng cho các hoạt động dấu phẩy động của phần mềm trong khi exe của bạn được biên dịch giả sử hỗ trợ phần cứng cho dấu phẩy động. Trong ngắn hạn, bạn có thể ép phao mềm làm cờ biên dịch. (nếu bạn đang sử dụng gcc, tôi nghĩ đó là -msoft-float)

Về lâu dài, nếu bộ xử lý mục tiêu của bạn có hỗ trợ phần cứng cho các hoạt động dấu phẩy động, nói chung, bạn sẽ muốn xây dựng hoặc tìm một chuỗi công cụ chéo có bật phần cứng float để tăng tốc độ. Một số họ bộ xử lý có các biến thể kiểu máy, một số có và một số không hỗ trợ phần cứng. Vì vậy, ví dụ, chỉ nói bộ xử lý của bạn là ARM là không đủ để biết liệu bạn có hỗ trợ dấu chấm động phần cứng hay không.


8

Việc tính toán có thể được thực hiện bằng phần cứng dấu phẩy động hoặc trong phần mềm dựa trên số học số nguyên.

Làm điều đó trong phần cứng nhanh hơn nhiều, nhưng nhiều bộ vi điều khiển không có phần cứng dấu phẩy động. Trong trường hợp đó, bạn có thể tránh sử dụng dấu phẩy động (thường là tùy chọn tốt nhất) hoặc dựa vào triển khai trong phần mềm, phần mềm này sẽ là một phần của thư viện C.

Trong một số họ bộ điều khiển, ví dụ như ARM, phần cứng dấu phẩy động hiện diện trong một số mô hình của họ nhưng không có trong các kiểu khác, vì vậy gcc cho các họ này hỗ trợ cả hai. Vấn đề của bạn dường như là bạn đã trộn lẫn hai tùy chọn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.