2015-05-28 9 views
6

Jestem w trakcie korzystania z wysyłania procesora w oparciu o funkcje procesora, aby przełączyć implementację skomplikowanego algorytmu numerycznego. Chcę dołączyć dwie wersje (wersję sse2 i sse3 dla argumentów) Kompiluję w tej samej dynamicznej bibliotece.Unikanie powtarzania symbolu podczas kompilowania do wielu zestawów instrukcji

Dotychczasowe podejście polegało na zawarciu całego kodu architektury do przestrzeni nazw, np. namespace sse2 i namespace sse3 i tym samym unika się powielania nazw symboli podczas łączenia z ostateczną biblioteką dynamiczną.

Co jednak się stanie, jeśli użyję kodu spoza mojej kontroli (np. std::vector<int>) zarówno w wersji sse2, jak i ss3. O ile widzę, implementacja std::vector będzie obecna zarówno w plikach obiektów sse2, jak i sse3, ale teoretycznie może zawierać różne instrukcje w zależności od optymalizacji wykonywanych przez kompilator. Kiedy połączę te pliki obiektów z biblioteką dynamiczną, jedna z nich zostanie wykorzystana i ryzykuję potencjalnie próbą uruchomienia instrukcji sse3 na procesorze obsługującym tylko sse2.

Oprócz kompilacji do dwóch oddzielnych bibliotek dynamicznych, co można zrobić, aby obejść ten problem? Potrzebuję rozwiązania działającego zarówno w Visual Studio, jak i klangu w systemie Windows, Mac OS X i Linux.

+0

'std :: vector' zostanie zaimplementowany w bibliotece dynamicznej lub bibliotece statycznej połączonej z twoim obiektem (np. W glibc). Twoje pliki obiektowe powinny zawierać tylko deklarację 'std :: vector', a nie implementację/definicję. Jaki jest problem? –

+0

Po pierwsze, std :: vector był tylko przykładem. Mówię także o innych bibliotekach stron trzecich, które mogą być tylko nagłówkami. Po drugie, std :: vector jest szablonem, więc kod będzie obecny w moich własnych plikach obiektowych. –

+0

[To może Cię zainteresować] (https://stackoverflow.com/questions/30320369/alias-of-a-function-template). Jeśli używasz biblioteki z pliku nagłówkowego, upewnij się, że wszystkie funkcje są wbudowane statycznie. To jest to co robię. –

Odpowiedz

0

Jednym ze sposobów byłoby wysłanie na poziomie biblioteki współdzielonej zamiast poziomu pliku obiektów. Wymagałoby to wielokrotnego kompilowania całej biblioteki przy pomocy różnych zestawów instrukcji, a następnie wysyłania do odpowiedniej biblioteki współdzielonej w czasie wykonywania w zależności od wykrywanych możliwości procesora. Szczegółowo opisuję podejście, które może nad tym pracować w systemie OS X i Linux in this previous answer. Jednak nie próbowałem tego zaimplementować w systemie Windows (jeszcze).

+0

Jest to z pewnością interesujące rozwiązanie, które zamieściłeś w drugiej odpowiedzi. Jednak, jak stwierdziłem w pytaniu, wolałbym robić to tylko z jedną biblioteką dynamiczną. Wiem, jak to zrobić z wieloma bibliotekami, choć w mniej sprytny sposób, niż sugerujesz, –

-3

Ten scenariusz jest w pełni obsługiwany w języku i nie powinien wymagać jawnej obsługi. Twój dynamiczny scenariusz wysyłki nie ma z tym wiele wspólnego - bardzo typowe dla projektu jest tworzenie std :: vector w wielu jednostkach tłumaczeniowych, a mimo to ODR nie jest naruszany. Zasadniczo funkcje śródliniowe - aw szczególności instancje szablonów - są po prostu niewidoczne dla łącznika (tj. Nie pojawiają się jako "Zewnętrzne" w tabelach plików obj).

Jeśli z jakiegoś egzotycznego powodu musiałbyś jawnie kontrolować ten typ powiązania, musiałbyś uciekać się do aparatu specyficznego dla kompilatora. Aparat MSVC to selectany, gcc ma some other devices. Nie wiem o klangu - ale chodzi o to, że trudno byłoby wymyślić powód, by użyć któregoś z nich.

+0

Kwestia, do której odnosi się PO, nie jest związana z ODR. Problem polega na tym, że różne instancje 'std :: vector ', na przykład, nie są wymienne w jego scenariuszu, ponieważ są skompilowane z różnym wsparciem zestawu instrukcji.Nie ma gwarancji, że wystąpienie szablonów zostanie zainicjowane, więc linker musi deduplikować różne wystąpienia danego symbolu. W przypadku OP nie ma możliwości, aby linker wiedział, które z różnych wystąpień byłyby do przyjęcia, a więc problem. –

+0

Dokładnie, JasonR. Wydaje się, że po połączeniu z najmniejszymi zestawami/biblioteką obiektów zestawu instrukcji, te implementacje są wybierane, co najmniej usuwa problem z próbą wykonania nieobsługiwanej instrukcji. Usuwa jednak wszelkie korzyści związane z wydajnością z tej części kodu. –

Powiązane problemy