Jest więcej kompilacji niż szybkość procesora i liczba dostępnych rdzeni: szerokość pasma dysku i pasma pamięci są bardzo ważne.
W twoim przypadku wyobrażam sobie, że każde z rodzeństwa HT procesora otrzymuje około 4 procesów do wykonania. Gdy zaczyna, blokuje się na dysku IO i przechodzi do następnego procesu. Drugi próbuje otworzyć drugi plik, blokuje na dysku IO, a rodzeństwo przenosi się do następnego procesu. Uruchomienie czterech kompilatorów przed pierwszym przygotowaniem dysku IO nie zdziwiłoby mnie.
Tak więc, kiedy pierwszy czytany jest w źródle programu, kompilator musi rozpocząć polowanie przez katalogi, aby znaleźć # zawarte pliki. Każdy z nich wymaga niektórych wywołań open(), po których następuje wywołanie read(), z których wszystkie mogą blokować, a wszystkie z nich zwalniają rodzeństwo, aby inne procesy mogły zostać uruchomione.
Teraz pomnóż to przez ośmioro rodzeństwa - każdy rdzeń HT będzie działał, aż zablokuje dostęp do pamięci, w którym to momencie zamieni się z innym rodzeństwem i będzie działał przez jakiś czas. Gdy pamięć pierwszego rodzeństwa zostanie przeniesiona do pamięci podręcznej, prawdopodobnie czas, aby drugie rodzeństwo się zatrzymało podczas oczekiwania na pamięć.
Istnieje górny limit na to, o ile szybciej można uzyskać kompilację do uruchomienia przy użyciu make -j
, ale dwa razy liczba z cpus był dobrym punktem wyjścia dla mnie w przeszłości.