Próbowałem wyczyścić stronę podręcznika GCC w tym celu, ale nadal nie rozumiem.
Jaka jest różnica między -march
i -mtune
?
Kiedy używa się tylko -march
, a kiedy obu? Czy jest to kiedykolwiek możliwe -mtune
?
Próbowałem wyczyścić stronę podręcznika GCC w tym celu, ale nadal nie rozumiem.
Jaka jest różnica między -march
i -mtune
?
Kiedy używa się tylko -march
, a kiedy obu? Czy jest to kiedykolwiek możliwe -mtune
?
Jeśli używasz, -march
GCC będzie mogło generować instrukcje, które działają na określonym CPU, ale (zazwyczaj) nie na wcześniejszych procesorach z rodziny architektur.
Jeśli tylko użyjesz -mtune
, kompilator wygeneruje kod, który działa na każdym z nich, ale faworyzuje sekwencje instrukcji, które działają najszybciej na określonym procesorze, który wskazałeś. np. ustawienie heurystyki rozwijania pętli odpowiednio dla tego procesora.
-march=foo
sugeruje, -mtune=foo
chyba że określisz również inny -mtune
. Jest to jeden z powodów, dla których używanie -march
jest lepsze niż tylko włączanie opcji, takich jak -mavx
bez robienia czegokolwiek w zakresie dostrajania.
Uwaga: -march=native
na procesorze, którego GCC nie rozpoznaje, będzie nadal włączał nowe zestawy instrukcji, które GCC może wykryć, ale pozostawi -mtune=generic
. Użyj wystarczająco nowego GCC, który wie o Twoim procesorze, jeśli chcesz, aby tworzył dobry kod.
march
sugerujemtune
. Zatem odpowiedzi na twoje zastrzeżenia brzmią odpowiednio: nie i tak.mtune
imarch
kombinacje. Ten post na blogu wyjaśniaOto, co wygooglowałem:
Ta
-march=X
opcja przyjmuje nazwę procesoraX
i umożliwia GCC generowanie kodu, który wykorzystuje wszystkie funkcjeX
. Podręcznik GCC wyjaśnia dokładnie, które nazwy procesorów oznaczają rodziny procesorów i ich funkcje.Ponieważ funkcje są zwykle dodawane, ale nie usuwane, plik binarny zbudowany za pomocą
-march=X
będzie działał na procesorzeX
, ma duże szanse na uruchomienie na procesorach nowszych niżX
, ale prawie na pewno nie będzie działał na niczym starszym niżX
. Pewne zestawy instrukcji (myślę, że 3DNow!) Mogą być specyficzne dla konkretnego producenta procesora, a ich użycie prawdopodobnie dostaniesz pliki binarne, które nie działają na konkurencyjnych procesorach, nowszych lub innych.Ta
-mtune=Y
opcja dostosowuje wygenerowany kod do szybszego działaniaY
niż na innych procesorach, na których może działać.-march=X
sugeruje-mtune=X
.-mtune=Y
nie zastąpi-march=X
, więc na przykład prawdopodobnie nie ma sensu-march=core2
i-mtune=i686
- Twój kod nie będzie działał na niczym starszym niż icore2
tak, z powodu-march=core2
, więc dlaczego na Ziemi miałbyś chcieć zoptymalizować pod kątem czegoś starszego (mniej funkcjonalnego) niż core2?-march=core2 -mtune=haswell
ma więcej sensu: nie używaj żadnych funkcji poza tym, cocore2
zapewnia (co wciąż jest o wiele więcej niż to, co-march=i686
ci daje!), ale optymalizuj kod dla znacznie nowszychhaswell
procesorów, a nie dlacore2
.Jest też
-mtune=generic
.generic
sprawia, że GCC tworzy kod, który działa najlepiej na obecnych procesorach (co oznaczageneric
zmiany z jednej wersji GCC na inną). Na forach Gentoo krążą plotki, że-march=X -mtune=generic
tworzy kod działający szybciejX
niż kod produkowany przez do-march=X -mtune=X
(lub po prostu-march=X
, jak-mtune=X
sugeruje). Nie mam pojęcia, czy to prawda, czy nie.Ogólnie, jeśli nie wiesz dokładnie, czego potrzebujesz, wydaje się, że najlepszym sposobem jest określenie
-march=<oldest CPU you want to run on>
i-mtune=generic
(-mtune=generic
jest tutaj, aby przeciwdziałać niejawnemu-mtune=<oldest CPU you want to run on>
, ponieważ prawdopodobnie nie chcesz optymalizować dla najstarszego procesora). Lub po prostu-march=native
, jeśli kiedykolwiek zamierzasz działać tylko na tej samej maszynie, na której budujesz.źródło
-march=native
, możesz chcieć sprecyzować-mtune=X
, ponieważ wartość domyślna nadal jest-mtune=generic
, jak omówiono tutaj: lemire.me/blog/2018/07/25/ ...-march=native
oznaczatune=native
to dobrze, jeśli używasz GCC, który wie o twoim procesorze. Ten artykuł przedstawia tylko zły przypadek. Nowsze wersje GCC generalnie generują lepszy kod, zwłaszcza przy użyciu nowych instrukcji, takich jak AVX2 i AVX-512. Posiadanie ustawień dostrajania (takich jak heurystyka rozwijania pętli) zaprojektowanych dla twojego procesora to zdecydowany plus. Więc jeśli zależy Ci na wydajności na tyle, aby korzystać z tych opcji, użyj nowego GCC, przynajmniej takiego, które wie o Twoim procesorze, najlepiej aktualnej stabilnej wersji.tune=generic
dla nowszego członka tej samej rodziny mikroarchitektur, zwłaszcza czegoś takiego jak Kaby Lake, które jest dosłownie identyczne z mikroarchitekturą Skylake. Ale myślę, że nadal ma inną rodzinę / stepping, więc GCC, który wiedział tylko o Skylake i starszym, może nie rozpoznać go do strojenia.