2010-07-23 13 views

Odpowiedz

81

Twarde pływaki używają jednostki zmiennoprzecinkowej na chipie. Soft floats emulują jeden w oprogramowaniu. Różnica polega na szybkości. Dziwne jest to, że obie są używane w tej samej docelowej architekturze, ponieważ chip ma albo jednostkę FPU, albo nie. Możesz włączyć miękki zmiennoprzecinkowy w GCC za pomocą -msoft-float. Możesz chcieć przekompilować swoją bibliotekę libc, aby używać sprzętowego punktu zmiennoprzecinkowego, jeśli go używasz.

+0

"Dziwnie jest widzieć oba używane w tej samej docelowej architekturze" Może to mieć sens dla biblioteki być niezależnym od maszyny i dokładnym bitem (miękki pływak) w częściach o dużej dokładności i szybkich (twarde pływaki) w częściach, w których małe odchylenia nie mają znaczenia. – PhilLab

10

Wygląda na to, że twoja biblioteka libc została zbudowana dla operacji zmiennoprzecinkowych w oprogramowaniu, podczas gdy twój exe został skompilowany przy założeniu obsługi sprzętu dla zmiennoprzecinkowej. W krótkim okresie można wymusić miękkie pływaki jako flagę kompilatora. (jeśli używasz gcc, myślę, że to -msoft-float)

Dłuższy okres, jeśli procesor twojego celu ma sprzętową obsługę operacji zmiennoprzecinkowych, zazwyczaj chcesz zbudować lub znaleźć krzyżowy zestaw narzędzi z włączonym spławem sprzętowym dla prędkość. Niektóre rodziny procesorów mają warianty modeli, niektóre z nich, a niektóre bez wsparcia sprzętowego. Na przykład, po prostu mówienie, że twój procesor jest ARM jest niewystarczające, aby wiedzieć, czy masz sprzętową obsługę zmiennoprzecinkowej.

28

Istnieją trzy sposoby, aby zrobić zmiennoprzecinkowych arytmetycznych:

  • instrukcjach użyto pływak jeśli procesor posiada FPU. (szybki)
  • Niech twój kompilator przetłumaczy arytmetykę zmiennoprzecinkową na arytmetykę całkowitą. (powolny)
  • Używaj instrukcji pływaka i procesora bez FPU. Twój procesor wygeneruje wyjątek (instrukcja zarezerwowana, instrukcja niezaimplementowana lub podobne), a jeśli jądro systemu operacyjnego zawiera emulator zmiennoprzecinkowy, będzie emulować te instrukcje (najwolniej).
6

Obliczenia można wykonać za pomocą sprzętu zmiennoprzecinkowego lub oprogramowania opartego na arytmetyce całkowitej.

Robiąc to w sprzęcie jest znacznie szybciej, ale wiele mikrokontrolerów nie ma sprzętu zmiennoprzecinkowego. W takim przypadku możesz albo unikać używania zmiennoprzecinkowego (zwykle najlepsza opcja), albo polegać na implementacji w oprogramowaniu, które będzie częścią biblioteki C.

W niektórych rodzinach kontrolerów, na przykład ARM, sprzęt zmiennoprzecinkowy występuje w niektórych modelach rodziny, ale nie w innych, więc gcc dla tych rodzin obsługuje oba. Twój problem polega na tym, że pomieszałeś dwie opcje.

11

Ściśle mówiąc, wszystkie te odpowiedzi wydają mi się błędne.

Kiedy kompiluję kod C za pomocą mojego krzyżowego toolchaina, linker drukuje strony z ostrzeżeniami mówiącymi, że mój plik wykonywalny używa hard floats, ale mój libc używa soft floats. Co za różnica?

Debian VFP wiki posiada informacje na temat trzech opcji dla -mfloat-abi,

  • soft - to czysta oprogramowanie
  • softfp - ten obsługuje FPU sprzętu, ale ABI jest miękka kompatybilne.
  • hard - ABI używa rejestrów float lub VFP.

Błąd łącznika (modułu ładującego) wynika z tego, że masz wspólną bibliotekę, która będzie przekazywać wartości zmiennoprzecinkowe w rejestrach całkowitych. Nadal możesz skompilować swój kod za pomocą -mfpu=vfp, itp., Ale powinieneś użyć -mfloat-abi=softfp, więc jeśli libc potrzebuje float, jest przekazywany w sposób zrozumiały dla biblioteki.

Jądro Linux może obsługiwać emulację instrukcji VFP. Oczywiście lepiej jest skompilować ten kod z -mfpu=none i mieć kompilator bezpośrednio generujący kod, zamiast polegać na emulacji jądra Linuksa. Uważam jednak, że błąd PO nie jest w rzeczywistości związany z tym problemem. Jest oddzielny i należy go również załatwić razem z -mfloat-abi.

Armv5 shared library with ArmV7 CPU jest przeciwieństwem tego; the libc był trudny, ale aplikacja była tylko miękka. Jest kilka sposobów na obejście problemu, ale rekompilacja z odpowiednimi opcjami jest zawsze najłatwiejsza.

Inną kwestią jest to, że jądro Linux musi obsługiwać zadania VFP (lub dowolny inny zmienny punkt ARM), aby zapisać/przywrócić rejestry w przełączniku kontekstu.

+0

Nowoczesne wersje GCC (~ 4.8 +) obsługują "multi-lib", które mają biblioteki twarde i miękkie. Wcześniejsze wersje wymagały kompilatora zbudowanego w określonej wersji. Czasami ścieżka do właściwej biblioteki jest potrzebna podczas łączenia z dystrybucją gcc "multi-lib", ponieważ istnieje kilka wersji bibliotek (wymagające dłuższego czasu na kompilację). Nazwy katalogów mogą mieć postać "hf", "hardf", "libhf" lub "hard-float", ale zwykle znajdują się pod zwykłym "miękkim" katalogiem lub w pobliżu. –

+0

To jest właściwa odpowiedź. Konwersja wywołań dla elementów pływających musi pasować do kodu i biblioteki libc. Może nadal działać z niedopasowaniem, jeśli nigdy nie będziesz wywoływał żadnych funkcji zmiennoprzecinkowych libc. –

Powiązane problemy