Apa perbedaan antara angka floating point keras dan lunak?


98

Ketika saya mengkompilasi kode C dengan toolchain lintas saya, linker mencetak halaman peringatan yang mengatakan bahwa executable saya menggunakan float keras tetapi libc saya menggunakan float lunak. Apa bedanya?


Jika ini adalah arsitektur ARM, harap masukkan ke dalam tag :-)
Nils Pipenbrinck

3
@Nils Pipenbrinck: Chip MIPS juga mengalami masalah ini
Javier

Jawaban:


100

Pelampung keras menggunakan unit floating point on-chip. Soft float meniru satu perangkat lunak. Perbedaannya adalah kecepatan. Aneh melihat keduanya digunakan pada arsitektur target yang sama, karena chip tersebut memiliki FPU atau tidak. Anda dapat mengaktifkan titik mengambang lunak di GCC dengan -msoft-float. Anda mungkin ingin mengkompilasi ulang libc Anda untuk menggunakan titik mengambang perangkat keras jika Anda menggunakannya.


3
"Aneh rasanya melihat keduanya digunakan pada arsitektur target yang sama" Ini dapat dimengerti jika perpustakaan menjadi tidak tergantung mesin dan bit-tepat (pelampung lembut) di bagian yang kritis keakuratan dan cepat (pelampung keras) di bagian di mana penyimpangan kecil tidak terjadi tidak masalah.
PhilLab

Itu terjadi pada ARM 32-bit.
Aaron Franke

31

Ada tiga cara untuk melakukan aritmatika floating point:

  • Gunakan instruksi float jika CPU Anda memiliki FPU. (cepat)
  • Minta kompiler Anda menerjemahkan aritmatika floating point ke aritmatika integer. (lambat)
  • Gunakan instruksi float dan CPU tanpa FPU. CPU Anda akan membuat pengecualian (Instruksi yang Dicadangkan, Instruksi yang Tidak Diimplementasikan, atau yang serupa), dan jika kernel OS Anda menyertakan emulator titik mengambang, ia akan meniru instruksi tersebut (paling lambat).

23

Sebenarnya, semua jawaban ini tampak salah bagi saya.

Ketika saya mengkompilasi kode C dengan toolchain lintas saya, linker mencetak halaman peringatan yang mengatakan bahwa executable saya menggunakan float keras tetapi libc saya menggunakan float lunak. Apa bedanya?

Wiki Debian VFP memiliki informasi tentang tiga pilihan untuk -mfloat-abi,

  • soft - ini adalah perangkat lunak murni
  • softfp- ini mendukung FPU perangkat keras, tetapi ABI kompatibel dengan perangkat lunak.
  • hard- ABI menggunakan register float atau VFP .

Kesalahan penaut (pemuat) adalah karena Anda memiliki pustaka bersama yang akan meneruskan nilai titik mengambang dalam register bilangan bulat. Anda masih dapat mengkompilasi kode Anda dengan a -mfpu=vfp, dll, tetapi Anda harus menggunakannya -mfloat-abi=softfpsehingga jika libc membutuhkan float, kode tersebut akan diteruskan dengan cara yang dipahami oleh perpustakaan.

Kernel Linux dapat mendukung emulasi instruksi VFP. Jelas, Anda lebih baik mengkompilasi -mfpu=noneuntuk kasus ini dan meminta kompilasi menghasilkan kode secara langsung daripada mengandalkan emulasi kernel Linux apa pun. Namun, saya tidak percaya kesalahan OP sebenarnya terkait dengan masalah ini. Ini terpisah dan juga harus ditangani bersama dengan -mfloat-abi.

Perpustakaan bersama Armv5 dengan CPU ArmV7 adalah kebalikan dari yang satu ini; yang libc itu mengambang keras tetapi aplikasi itu hanya lembut . Ada beberapa cara untuk mengatasi masalah tersebut, tetapi mengompilasi ulang dengan opsi yang benar selalu yang termudah.

Masalah lainnya adalah bahwa kernel Linux harus mendukung tugas VFP (atau titik mengambang ARM apa pun yang ada) untuk menyimpan / memulihkan register pada sakelar konteks.


1
Versi GCC (~ 4.8 +) modern mendukung 'multi-lib', yang memiliki library hard float dan soft float. Versi sebelumnya mengharuskan Anda memiliki kompiler yang dibangun dengan versi tertentu. Terkadang jalur ke pustaka yang benar diperlukan saat menautkan dengan distribusi gcc 'multi-lib' karena ada beberapa versi pustaka (memerlukan waktu lebih lama untuk membuat kompiler). Nama direktori mungkin 'hf', 'hardf', 'libhf', atau 'hard-float' tetapi biasanya berada di bawah direktori 'soft' biasa atau lokasi terdekat.
kebisingan tanpa seni

Ini adalah jawaban yang benar. Konversi panggilan untuk float harus cocok antara kode Anda dan libc. Ini mungkin masih berfungsi dengan ketidakcocokan, jika Anda tidak pernah memanggil fungsi libc floating point.
Tor Klingberg

13

Sepertinya libc Anda dibuat untuk operasi floating point perangkat lunak sementara exe Anda dikompilasi dengan asumsi dukungan perangkat keras untuk floating point. Dalam jangka pendek, Anda bisa memaksa pelampung lembut sebagai bendera penyusun. (jika Anda menggunakan gcc, saya pikir itu -msoft-float)

Jangka panjang, jika prosesor target Anda memiliki dukungan perangkat keras untuk operasi titik mengambang, Anda biasanya ingin membangun atau menemukan rantai alat silang dengan pelampung perangkat keras yang diaktifkan untuk kecepatan. Beberapa keluarga prosesor memiliki varian model beberapa dengan dan beberapa tanpa dukungan perangkat keras. Jadi, misalnya, hanya mengatakan prosesor Anda adalah ARM tidak cukup untuk mengetahui apakah Anda memiliki dukungan floating point perangkat keras.


8

Perhitungan dapat dilakukan baik dengan perangkat keras floating-point atau dalam perangkat lunak berdasarkan aritmatika integer.

Melakukannya di perangkat keras jauh lebih cepat, tetapi banyak mikrokontroler tidak memiliki perangkat keras floating-point. Dalam hal ini Anda dapat menghindari penggunaan floating point (biasanya pilihan terbaik) atau mengandalkan implementasi dalam perangkat lunak, yang akan menjadi bagian dari pustaka C.

Di beberapa keluarga pengontrol, misalnya ARM, perangkat keras floating-point ada di beberapa model keluarga tetapi tidak di model lain, jadi gcc untuk keluarga ini mendukung keduanya. Masalah Anda tampaknya adalah Anda mencampurkan kedua opsi tersebut.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.