2012-09-23 13 views
5

Czy mogę utworzyć uniwersalny plik binarny dla systemu Mac OS X zawierający dwie wersje mojej aplikacji, skompilowaną z SSE4.2 i skompilowaną przy użyciu SSE3?Uniwersalny kod binarny dla różnych wersji SSE

W tym przypadku wersja skompilowana z SSE4.2 zostanie automatycznie załadowana do procesora obsługującego SSE4.2.

Jeśli nie, chciałbym otrzymywać sugestie dotyczące uruchomienia mojej aplikacji na starych procesorach, które nie obsługują SSE4.2, ale wykorzystują SSE4.2 na procesorze, który ją obsługuje.

Pamiętaj, że kierujemy reklamy do sklepu Mac AppStore, jeśli to ma znaczenie. Używam Clang z Xcode 4.5.

+0

Wszystko, co musisz zrobić, to: 1) Wykryć zestaw instrukcji. 2) Rozgałęz się do wersji, którą chcesz. – Mysticial

+0

[Moja odpowiedź tutaj pokazuje, jak wykryć zestaw instrukcji.] (Http://stackoverflow.com/a/7495023/922184) Własność '__cpuid()' jest specyficzna dla MSVC. W GCC można uzyskać do niego dostęp za pomocą wbudowanego zestawu. Nie jestem pewien, co używasz, ale powinien być sposób, aby uzyskać do niego dostęp. – Mysticial

+0

Wolę nie zmieniać plików kodu źródłowego, ponieważ niektóre linie, które nie działają na starych procesorach, pochodzą z zewnętrznych projektów open source. –

Odpowiedz

3

Nie jest to obsługiwane przez format Mach-O używany przez system Mac OS X. Format umożliwia tworzenie plików binarnych dla różnych architektur. Istnieje pole podtypu, ale są tylko wartości zdefiniowane dla różnych generacji procesorów, a nie ich możliwości.

Istnieje kilka sposobów obejścia tego problemu. Jednym z nich byłoby posiadanie zarówno SSE4.2, jak i kodu dla starszych procesorów wbudowanych w ten sam plik binarny, używając różnych nazw funkcji. Twój kod określa, czy obsługiwany jest SSE4.2, a następnie wywołaj odpowiednią funkcję.

Inną opcją byłoby zbudowanie dwóch bibliotek, jednej z SSE4.2 i jednej bez, i wysłania obu z nich w pakiecie aplikacji, ale bez linków do nich. Kiedy zostanie załadowany po raz pierwszy, Twój kod określa, czy obsługiwana jest wersja SSE4.2, a następnie ładuje odpowiednią bibliotekę.

Używając pierwszej metody, nie musisz się martwić o załadowanie biblioteki i połączenie wszystkich funkcji, ale zawsze będziesz ładował dodatkowy kod, który nie zostanie wykonany, i będziesz musiał sprawdzić zmienną przed każdym tych wywołań funkcji. Za pomocą drugiej metody można po prostu wywoływać funkcje bez sprawdzania czegokolwiek za każdym razem, ale ładowanie biblioteki i łączenie wszystkich funkcji jest więcej pracy niż po prostu porównywanie zmiennej za każdym razem.

Powiązane problemy