Dlaczego program wymagałby określonej minimalnej liczby rdzeni procesora?

55

Czy jest możliwe napisanie kodu (lub kompletnego oprogramowania zamiast fragmentu kodu), który nie będzie działał poprawnie, jeśli zostanie uruchomiony na procesorze, który ma mniej niż N liczby rdzeni? Bez wyraźnego sprawdzenia i celowego niepowodzenia:

JEŻELI (noOfCores <4) NASTĘPNIE nie działają poprawnie celowo

Patrzę na minimalne wymagania systemowe gry ( Dragon Age: Inkwizycja ) i określa minimum czterordzeniowy procesor. Wielu graczy twierdzi, że NIE działa na dwurdzeniowych procesorach, a NAWET na Intel Core i3s z dwoma fizycznymi i dwoma logicznymi rdzeniami. I to NIE jest problem mocy obliczeniowej.

Z mojego zrozumienia, wątki są całkowicie odizolowane od procesora przez system operacyjny, ponieważ nie można tego zrobić.

Żeby to wyjaśnić:

Ja nie pytać „Czy mogę dowiedzieć się liczby rdzeni procesora z kodem, a nie celowo?” ... Taki kod byłby w złym zamiarze (zmusza cię do zakupu droższego procesora do uruchomienia programu - bez potrzeby korzystania z mocy obliczeniowej). Pytam, czy twój kod, powiedzmy, ma cztery wątki i kończy się niepowodzeniem, gdy dwa wątki są uruchamiane na tym samym rdzeniu fizycznym (bez jawnego sprawdzania informacji o systemie i celowego niepowodzenia) .

Krótko mówiąc, czy może istnieć oprogramowanie, które wymaga wielu rdzeni bez potrzeby dodatkowej mocy obliczeniowej pochodzącej z wielu rdzeni? Wymagałoby to tylko N osobnych rdzeni fizycznych.

uylmz
źródło
11
Jeśli uważnie przeczytasz moje pytanie, zobaczysz, że nie zadają tego samego.
uylmz
21
Ponieważ liczba rdzeni może być odzyskana, można ją porównać do N, a jeśli to porównanie da wartość prawda, kod może zrobić, co tylko zechce, w tym, ale nie ograniczając się do zachowań, które nie są reklamowane. Jakie jest Twoje pytanie?
3
Czy jesteś pewien, że problem jest naprawdę i bezpośrednio związany z liczbą rdzeni? Może wspomniana gra jest częściowo oparta tylko na funkcji (poprawnie) dostarczanej przez CPU z co najmniej 4 rdzeniami?
mgoeminne,
25
Pamiętaj, że „minimalne wymagania systemowe” to często „minimalne wymagania systemowe do działania z akceptowalną wydajnością”, szczególnie w przypadku gier. Jest bardzo możliwe, że Dragon Age teoretycznie może działać na jednym rdzeniu, ale jeśli to zrobisz, pokazałby ogromne spadki klatek. Wymagają więc takiej liczby rdzeni, aby nie zmuszać Cię do zakupu sprzętu, ale aby uniknąć reklamacji jakościowych ze strony użytkowników sprzętu niższej klasy.
Gort the Robot
3
@Sebb: Myślę, że masz coś na uwadze: jeśli 4 fizyczne rdzenie korelują z posiadaniem większej pamięci podręcznej niż 2 fizyczne / 4 logiczne, wtedy gra mogłaby oczywiście zadławić się na komputerach 2x2 bez osiągania limitów mocy przetwarzania, ponieważ brakuje pamięci podręcznej czas. Test polegałby na znalezieniu procesora z 2x2 rdzeniami i dużą ilością pamięci podręcznej lub 4 rdzeniami i małą pamięcią podręczną, i zobaczyć, co się stanie.
Steve Jessop

Odpowiedzi:

45

Może być to możliwe „przypadkowo” z nieostrożnym wykorzystaniem powinowactwa rdzenia. Rozważ następujący pseudokod:

  • rozpocząć wątek
  • w tym wątku dowiedz się, na którym rdzeniu działa
  • ustawić powinowactwo procesora do tego rdzenia
  • zacznij na zawsze robić coś intensywnie obliczeniowego / zapętlić

Jeśli uruchomisz cztery z nich na dwurdzeniowym procesorze, albo coś pójdzie nie tak z ustawieniem powinowactwa rdzenia, albo skończysz z dwoma wątkami blokującymi dostępne rdzenie i dwoma wątkami, które nigdy nie zostaną zaplanowane. W żadnym momencie nie zapytano wyraźnie, ile rdzeni jest w sumie.

(Jeśli masz długotrwałe wątki, ustawienie powinowactwa procesora ogólnie poprawia przepustowość)

Pomysł, że firmy produkujące gry „zmuszają” ludzi do kupowania droższego sprzętu bez uzasadnionego powodu, nie jest zbyt prawdopodobny. Może tylko stracić ich klientów.

Edycja: ten post ma teraz 33 pozytywne głosy, co jest dość spore, biorąc pod uwagę, że opiera się na wyuczonym zgadywaniu!

Wygląda na to, że ludzie mają DA: źle uruchomić na systemach dwurdzeniowych: http://www.dsogaming.com/pc-performance-analyses/dragon-age-inquisition-pc-performance-analysis/ Ta analiza wspomina, że ​​sytuacja znacznie się poprawia, jeśli włączony jest hyperthreading. Biorąc pod uwagę, że HT nie dodaje żadnych jednostek wydających instrukcje ani pamięci podręcznej, po prostu pozwala na uruchomienie jednego wątku, podczas gdy inny jest zawieszony w pamięci podręcznej, co zdecydowanie sugeruje, że jest on powiązany wyłącznie z liczbą wątków.

Inny plakat twierdzi, że zmiana sterowników grafiki działa: http://answers.ea.com/t5/Dragon-Age-Inquisition/Working-solution-for-Intel-dual-core-CPUs/td-p/3994141 ; Biorąc pod uwagę, że sterowniki graficzne są zwykle nędznym ulem szumowiny i wioski, nie jest to zaskakujące. Jeden notoryczny zestaw sterowników miał tryb „poprawny i wolny” w porównaniu z „szybkim i niepoprawnym”, który został wybrany, jeśli został wywołany z QUAKE.EXE. Jest całkiem możliwe, że sterowniki zachowują się inaczej dla różnej liczby pozornych procesorów. Być może (powrót do spekulacji) zastosowano inny mechanizm synchronizacji. Niewłaściwe użycie blokad ?

„Niewłaściwe użycie operacji podstawowych blokowania i synchronizacji” jest bardzo, bardzo częstym źródłem błędów. (Błąd, na który powinienem patrzeć w pracy podczas pisania, to „awaria, jeśli zmieniam ustawienia drukarki w tym samym czasie, co kończy się zadanie drukowania”).

Edycja 2: komentarze wspominają, że OS próbuje uniknąć głodu wątków. Zauważ, że gra może mieć swój wewnętrzny quasi-harmonogram do przypisywania pracy do wątków, i będzie podobny mechanizm w samej karcie graficznej (który w rzeczywistości jest własnym systemem wielozadaniowym). Szanse na błąd w jednym z nich lub interakcja między nimi są dość wysokie.

www.ecsl.cs.sunysb.edu/tr/ashok.pdf (2008) to praca dyplomowa na temat lepszego planowania kart graficznych, w której wyraźnie wspomniano, że zwykle używają planowania według kolejności zgłoszeń, co jest łatwe do wdrożenia w systemy nieprewencyjne. Czy sytuacja się poprawiła? Prawdopodobnie nie.

pjc50
źródło
1
Tak, odpowiedź na to pytanie składa się z dwóch części: koligacja procesora pozwala kodować coś, co uczyniłoby to wymaganiem technicznym w systemie Windows, alternatywną odpowiedzią jest to, że systemy czasu rzeczywistego mogą zdecydowanie wymagać takich rzeczy. +1 za bycie jedyną osobą, która wspomniała o powinowactwie do procesora, co jest naprawdę najbardziej prawdopodobnym winowajcą tego, o co tu pytamy.
Jimmy Hoffa
3
Co może pójść źle, jeśli ustawisz powinowactwo do bieżącego rdzenia? W przypadku wielozadaniowości zapobiegawczej oczekujący wątek zostanie zaplanowany, chyba że bieżący ma najwyższy możliwy priorytet („w czasie rzeczywistym” w systemie Windows). Widziałbym inny scenariusz: każdemu z 4 wątków przypisano statycznie zdefiniowane powinowactwo 1,2,4,8, w którym to przypadku dwa ostatnie wątki nigdy nie zostaną zaplanowane (chociaż nie jestem pewien, czy ustawienie powinowactwa na skuteczne zero odniesie sukces).
Ruslan
@ Ruslan Być może próba ustawienia nieprawidłowego powinowactwa spowoduje awarię aplikacji?
Luaan
1
@Luaan cóż, to nie jest tak ryzykowna operacja, aby doprowadzić do awarii. Maksymalnie oczekiwałbym błędu zwracanego przez system operacyjny. Właśnie sprawdziłem, w systemie Linux pojawia się błąd „Nieprawidłowy argument”. Nie wiem, co by powiedział Windows.
Ruslan
@Ruslan Każdy większy system operacyjny od ponad dekady zawiera kod zapobiegający głodowaniu wątków (zwykle poprzez zwiększenie priorytetu wątku, gdy nie działa on wystarczająco długo).
Voo
34

Może być konieczne posiadanie 4 rdzeni, ponieważ aplikacja uruchamia cztery zadania w równoległych wątkach i oczekuje, że zakończą się prawie jednocześnie.

Gdy każdy wątek jest wykonywany przez osobny rdzeń, a wszystkie wątki mają dokładnie takie samo obciążenie obliczeniowe, istnieje duże prawdopodobieństwo (ale nie jest to gwarantowane), że zakończą się mniej więcej w tym samym czasie. Ale kiedy dwa wątki działają na jednym rdzeniu, taktowanie będzie znacznie mniej przewidywalne, ponieważ rdzeń będzie cały czas przełączał kontekst między dwoma wątkami.

Błędy występujące z powodu nieoczekiwanego czasu wątku są nazywane „ warunkami wyścigu ”.

W kontekście rozwoju gry jedną z możliwych architektur z tego rodzaju problemem może być ta, w której różne funkcje gry są symulowane w czasie rzeczywistym przez różne wątki procesora. Gdy każda funkcja działa na własnym rdzeniu, wszystkie są symulowane z mniej więcej taką samą prędkością. Ale gdy dwie funkcje działają na jednym rdzeniu, obie będą symulowane tylko o połowę szybciej niż reszta świata gry, co może powodować różnego rodzaju dziwne zachowania.

Zauważ, że architektura oprogramowania, która zależy od niezależnych wątków działających w określonych momentach czasowych, jest wyjątkowo delikatna i jest oznaką bardzo złego zrozumienia współbieżnego programowania. W praktycznie wszystkich wielowątkowych interfejsach API dostępne są funkcje umożliwiające jawną synchronizację wątków w celu zapobiegania tego rodzaju problemom.

Philipp
źródło
11
Ale każda gra ma delikatną zależność od tego, czy jest w stanie ukończyć obliczenia dla następnej klatki w czasie, aby renderować ją z rozsądną częstotliwością. Nawet jeśli twoje 4 wątki są poprawnie zsynchronizowane, renderowanie w odpowiednim czasie może być niemożliwe i nie ma korzyści w grze, która jest poprawna obliczeniowo, ale nie można jej odtworzyć z powodu opóźnień i zacinania się.
Bezużyteczne
1
@Useless: To nie do końca prawda. Możesz na przykład buforować ramki lub dane symulacyjne, aby ukryć wszelkie jąkanie, a istnieją równoczesne projekty, które są bardziej spójne. Wykonanie całego przetwarzania w X czasie i wymaganie dokładnej synchronizacji tego przetwarzania to różne sprawy.
DeadMG,
23
„architektura oprogramowania zależna od niezależnych wątków działających w określonych momentach jest wyjątkowo delikatna” Właśnie dlatego nie wyobrażam sobie gry, która w ogóle nie działa z 2 rdzeniami, ale niezawodnie działa z 4 rdzeniami. Nawet z 4 rdzeniami, czas będzie nieprzewidywalny, więc warunki wyścigu również wystąpiłyby, nawet jeśli rzadziej.
sick
8
@svick oczywiście. Ale pytanie brzmi „czy to możliwe?” nie „czy to jest normalne?”
user253751
5
Każdy kod z tego rodzaju „warunkami wyścigowymi” jest całkowicie uszkodzony , bez względu na to, ile rdzeni go uruchomisz. (Zwłaszcza, że ​​nie ma absolutnie żadnej gwarancji, co jeszcze działa w systemie.) Poważnie wątpię, aby to była przyczyna, biorąc pod uwagę, jak łatwo potknąłby się w grę nawet w systemie heksakorowym ...
DevSolar
16

Jest mało prawdopodobne, aby te „minimalne wymagania” reprezentowały coś, poniżej czego gra nie będzie działać. O wiele bardziej prawdopodobne jest to, że reprezentują coś, poniżej którego gra nie będzie działać z zadowalającą wydajnością. Żadna firma produkująca gry nie chce mieć do czynienia z wieloma klientami narzekającymi na kiepską wydajność, gdy działają na jednym rdzeniu 1 GHz, nawet jeśli oprogramowanie może technicznie działać. Prawdopodobnie więc celowo projektują tak, aby zawiodły mocno na urządzeniach z mniejszą liczbą rdzeni, niż dałoby to akceptowalną wydajność.

Jednym z ważnych wskaźników wydajności gry jest liczba klatek na sekundę. Zazwyczaj działają z prędkością 30 lub 60 klatek na sekundę. Oznacza to, że silnik gry musi renderować bieżący widok ze stanu gry w ustalonym czasie. Aby osiągnąć 60 fps, ma to nieco ponad 16 ms. Gry z wysokiej klasy grafiką są wyjątkowo związane z procesorem, więc istnieje ogromna korzyść między próbą podniesienia jakości (co zajmuje więcej czasu) a potrzebą pozostania w tym budżecie czasowym. W związku z tym budżet czasowy dla każdej klatki jest wyjątkowo napięty.

Ponieważ budżet czasu jest napięty, deweloper idealnie chce wyłącznego dostępu do jednego lub więcej rdzeni. Prawdopodobnie chcą też móc wykonywać swoje renderingi wyłącznie w rdzeniu, ponieważ to właśnie należy zrobić przy tym budżecie czasu, podczas gdy inne rzeczy, takie jak obliczanie stanu świata, odbywają się w osobnym procesie, w którym nie będzie to możliwe niepokoić.

Teoretycznie możesz wcisnąć to wszystko w jeden rdzeń, ale wtedy wszystko staje się znacznie trudniejsze. Nagle musisz upewnić się, że wszystkie rzeczy związane z grą zdarzają się wystarczająco szybko i pozwalają na renderowanie. Nie możesz po prostu zrobić z nich dwóch wątków oprogramowania, ponieważ nie ma sposobu, aby system operacyjny zrozumiał, że „wątek A musi wykonać X pracy w 16 ms, niezależnie od tego, co robi wątek B”.

Twórcy gier nie są zainteresowani kupowaniem nowego sprzętu. Powodem, dla którego mają wymagania systemowe, jest to, że koszt obsługi maszyn niższej klasy nie jest tego wart.

Gort the Robot
źródło
Chociaż jest to prawda, zdarza się, że można kupić sprzęt dwurdzeniowy, który jest wystarczająco silny, aby mógł osiągnąć więcej w danym przedziale czasowym niż sprzęt czterordzeniowy opisany w minimalnych specyfikacjach. Dlaczego sprzedawca miałby nie podawać takiego sprzętu jako akceptowalnego, co może spowodować jedynie utratę sprzedaży?
Jules
4
Rzeczą do porównania nie są rdzenie 2 na 4. Zasadniczo jest to 1 na 3 rdzenie, ponieważ procesor nr 0 będzie właściwie związany ze sterownikiem graficznym i DPC. Istnieją również znaczące efekty pamięci podręcznej i migracji, jeśli przesadzisz z procesorem z kilkoma rodzajami zadań w typowym systemie zadań współczesnej gry. Jest to wymagane, ponieważ Frostbite (silnik DA: I) został zaprojektowany od podstaw z bardzo starannym dostrajaniem, które wymaga określonej liczby rdzeni.
Lars Viklund,
6
@LarsViklund Wygląda na to, że znasz więcej szczegółów niż ktokolwiek tutaj. Czy zastanawiałeś się nad odpowiedzią?
Gort the Robot
1
„Jest mało prawdopodobne, aby te„ minimalne wymagania ”reprezentowały coś, poniżej czego gra nie będzie działać. Znacznie bardziej prawdopodobne jest, że reprezentują coś, poniżej którego gra nie będzie działać z zadowalającą wydajnością”. - G3258 Intela jest bardzo wydajnym dwurdzeniowym procesorem szeroko stosowanym przez graczy, który jest w stanie uruchomić gry równe lub wymagające większych zasobów niż Dragon Age Inkwizycja, ale wielu graczy twierdzi, że gra na nim nie działa.
uylmz
2
@ Reek Wątpię, aby użytkownik końcowy mógł łatwo stwierdzić, jak intensywna jest gra w porównaniu z inną.
Gort the Robot
9

Trzy wątki w czasie rzeczywistym, które nigdy nie śpią i jeden inny wątek. Jeśli jest mniej niż cztery rdzenie, czwarty wątek nigdy się nie uruchamia. Jeśli czwarty wątek musi komunikować się z jednym z wątków w czasie rzeczywistym, aby zakończyć wątek w czasie rzeczywistym, kod nie zakończy się z mniej niż czterema rdzeniami.

Oczywiście, jeśli wątki w czasie rzeczywistym czekają na coś, co nie pozwala im spać (np. Spinlock), projektant programu spieprzył.

Jozuego
źródło
1
Prawdopodobnie, gdy aplikacja użytkownika prosi przede wszystkim o wątki w czasie rzeczywistym, projektant spieprzył: D
Luaan
2
Zrobiłem to. Pół miliona linii kodu. Jeden przypadek z wykorzystaniem około 300 linii. Wątek czasu rzeczywistego spędza większość czasu na oczekiwaniu na dane wejściowe, dzięki czemu może znacznik czasowy wejść i przekazać go wątkowi o mniejszym priorytecie.
Jozuego
2
@Luaan W przypadku większości aplikacji zgodziłbym się z tobą, ale gry są inną bestią, podobnie jak aplikacje osadzone. W obu tych przypadkach troska o dobrą zabawę z innymi współbieżnymi aplikacjami wychodzi poza okno na korzyść wydajności.
reirab
Chociaż nie byłby szczególnie wydajny, ten scenariusz nie doprowadziłby do żadnych impasów - odwrócenie priorytetu by się tym zajęło (zakładając, że jakiś porządny harmonogram w jakimkolwiek głównym systemie operacyjnym ostatniej dekady)
Voo
2
@Joshua > Windows nie wie, co to jest inwersja priorytetowa. Co? support.microsoft.com/kb/96418 , msdn.microsoft.com/en-us/library/windows/desktop/ms684831.aspx . Inwersja priorytetów to także termin opisujący problem , a nie rozwiązanie (@Voo).
Bob
3

Przede wszystkim wątki programowe nie mają nic wspólnego z wątkami sprzętowymi i często są pomieszane. Wątki oprogramowania to fragmenty kodu, które można wysłać i uruchomić samodzielnie w kontekście procesu. Wątki sprzętowe są w większości zarządzane przez system operacyjny i są wysyłane do rdzenia procesora, gdy mówimy o zwykłych programach. Te wątki sprzętowe są wysyłane na podstawie obciążenia; sprzętowy dyspozytor wątków działa mniej więcej jak moduł równoważenia obciążenia.

Jednak jeśli chodzi o gry, szczególnie wysokiej klasy, czasami wątkami sprzętowymi zarządza sama gra lub gra instruuje dyspozytora wątków sprzętowych, co ma robić. Jest tak, ponieważ każde zadanie lub grupa zadań nie ma takiego samego priorytetu jak w normalnym programie. Ponieważ Dragon Age pochodzi z wysokiej klasy studia gier używającego wysokiej klasy silników do gier, mogę sobie wyobrazić, że używa on „ręcznej” wysyłki, a wtedy liczba rdzeni staje się minimalnym wymaganiem systemowym. Dowolny program ulegnie awarii, gdy wyślę kawałek kodu do 3. fizycznego rdzenia działającego na maszynie z tylko 1 lub 2 rdzeniami.

dj bazzie wazzie
źródło
To. Pamiętaj, że powiedzenie „sprawdź liczbę rdzeni” oznacza, że ​​firma produkuje oprogramowanie w określony sposób, aby zmusić użytkowników do zakupu droższego sprzętu (co byłoby niewłaściwe).
uylmz
2
Problemy te istnieją, dopóki istnieje gra na PC. Na początku mieliśmy 486dx i 486sx, później MMX i nie-MMX Pentium, rdzeń i non-core, a dziś mamy wymagania n-core. Jest to jeden z powodów, dla których konsole nadal istnieją.
dj bazzie wazzie
4
Czy znasz odniesienia do gier, które same przejmują procesor? O ile mi wiadomo, nie jest to bezpośrednio możliwe w systemie Windows, a przynajmniej nie w sposób, który zawiódłby w sposób, który sugerujesz.
Jules
2
@ djbazziewazzie w rzeczywistości system Windows udostępnia interfejs API, aby to zrobić, tj. ustaw wątek, aby zawsze korzystał z tego samego rdzenia; nazywa się to powinowactwem wątków i nie pozwala ręcznie wybrać, który fragment kodu uruchamia się gdzie i kiedy, i nie może powodować awarii systemu, jak sugerujesz (system zignoruje żądanie ustawienia powinowactwa na nieistniejący rdzeń, i po prostu planuj wątek do dowolnego rdzenia, gdy stanie się dostępny. Jestem prawie pewien, że tego właśnie używa id Tech, i tak naprawdę nie sprowadza się to do „zarządzania samymi wątkami sprzętowymi”.
Jules
1
@djbazziewazzie Wydaje się, że również źle rozumiesz sens Grand Central Dispatch, który nie daje programistom większej kontroli nad planowaniem rdzenia ich kodu; w rzeczywistości jego cel jest dokładnie odwrotny: wybór liczby tworzonych wątków i kodu, który powinien uruchamiać dany wątek z rąk aplikacji, aby można go było zoptymalizować pod kątem dostępnego sprzętu na poziomie całego systemu. Zależność od posiadania określonej liczby rdzeni jest dokładnie tym problemem, któremu GCD zaprojektowano, aby zapobiec.
Jules
1

Ponieważ możliwe jest użycie wirtualizacji w celu uzyskania większej liczby rdzeni wirtualnych niż fizycznych, a oprogramowanie nie wiedziałoby, że działa na wirtualizacji i zamiast tego uważa, że ​​ma tak wiele rdzeni fizycznych, powiedziałbym, że takie oprogramowanie nie jest możliwe.

Oznacza to, że nie można napisać oprogramowania, które zawsze zatrzyma się na rdzeniach mniejszych niż N.

Jak zauważyli inni, istnieją rozwiązania programowe, które mogą potencjalnie sprawdzić, szczególnie jeśli używany system operacyjny i kod mają niewielką ochronę przed warunkami wyścigu, gdy N procesów działa na <N procesorach. Prawdziwą sztuczką jest kod, który zawiedzie, gdy masz mniej niż N procesorów, ale nie zawiedzie, gdy masz N procesorów, ale system operacyjny, który może przypisać pracę mniej niż N procesorom.

Lawtonfogle
źródło
1

Możliwe, że są trzy wątki, które coś robią (generują tła lub generują ruch NPC) i przekazują zdarzenia do czwartej, która ma agregować / filtrować zdarzenia i aktualizować model widoku. Jeśli czwarty wątek nie otrzyma wszystkich zdarzeń (ponieważ nie jest zaplanowany na rdzeniu), model widoku nie zostanie poprawnie zaktualizowany. Może się to zdarzać sporadycznie, ale rdzenie te muszą być dostępne w dowolnym momencie. To może wyjaśniać, dlaczego przez cały czas nie widzisz dużego obciążenia procesora, ale gra i tak nie działa poprawnie.

TMN
źródło
1
W takim scenariuszu gra również zawiedzie losowo, gdy planowane jest uruchomienie usług w tle, co jest dość częste na większości komputerów.
Jules
1

Myślę, że Joshua zmierza właściwą ścieżką, ale nie do końca.

Załóżmy, że masz architekturę, w której są napisane trzy wątki, które robią tyle, ile mogą - kiedy skończą to, co robią, robią to ponownie. Aby zwiększyć wydajność, wątki te nie zwalniają kontroli - nie chcą ryzykować opóźnień w harmonogramie zadań systemu Windows. Tak długo, jak są 4 lub więcej rdzeni, działa to dobrze, nie działa źle, jeśli nie ma.

Zasadniczo byłoby to złe programowanie, ale gry to inna sprawa - gdy masz do wyboru między projektem gorszym na całym sprzęcie lub projektem, który jest lepszy na wystarczająco dobrym sprzęcie lub awarią na gorszym sprzęcie twórcy gier zwykle wybierają wymagać sprzętu.

Loren Pechtel
źródło
Zazwyczaj nie jest możliwe napisanie wątku, który nie zrzeknie się kontroli nad innymi wątkami. Wszystkie nowoczesne systemy operacyjne inne niż RTOS wykorzystują zapobiegawczą wielozadaniowość, która celowo uniemożliwia wątkowi (trybowi użytkownika) nie zwalnianie kontroli nad danym rdzeniem. Wątki jądra to oczywiście inna sprawa.
reirab
@reirab Boost to priorytet.
Loren Pechtel,
@Loren Nie zmienia faktu, że planista wciąż umiera, co oznacza, że ​​musisz dzielić czas z innymi wątkami o tym samym priorytecie, a program zwiększający priorytet brakujących wątków. Nie możesz tego zrobić na normalnych systemach operacyjnych, a nawet gdybyś mógł, gry z pewnością nie byłyby do przyjęcia.
Voo,
1

Is it possible to write code (or complete software, rather than a piece of code) that won't work properly when run on a CPU that has less than N number of cores?

Absolutnie. Wykorzystanie wątków w czasie rzeczywistym byłoby dobrym przykładem sytuacji, w której jest to nie tylko możliwe, ale pożądany (i często jedyny właściwy) sposób wykonania zadania. Jednak wątki w czasie rzeczywistym są zwykle ograniczone do jądra systemu operacyjnego, zwykle w przypadku sterowników, które muszą być w stanie zagwarantować, że jakieś zdarzenie sprzętowe zostanie obsłużone w określonym czasie. Nie powinieneś mieć wątków w czasie rzeczywistym w normalnych aplikacjach użytkownika i nie jestem pewien, czy można je nawet mieć w aplikacji w trybie użytkownika Windows. Zasadniczo systemy operacyjne celowo uniemożliwiają wykonanie tego z gruntów użytkowników właśnie dlatego, że pozwalają danej aplikacji przejąć kontrolę nad systemem.

W odniesieniu do aplikacji przeznaczonych dla użytkowników: Twoje założenie, że sprawdzanie określonej liczby wątków w celu uruchomienia jest z konieczności złośliwe, nie jest prawidłowe. Na przykład możesz mieć 2 długotrwałe zadania wymagające dużej wydajności, które wymagają dla siebie rdzenia. Bez względu na szybkość rdzenia procesora współdzielenie rdzenia z innymi wątkami może być poważnym i niedopuszczalnym spadkiem wydajności z powodu przeładowania pamięci podręcznej wraz z normalnymi karami nakładanymi za przełączanie wątków (które są dość znaczne). W takim przypadku byłoby to całkowicie uzasadnione, szczególnie w grze, aby ustawić każdy z tych wątków tak, aby miał powinowactwo tylko do jednego konkretnego rdzenia dla każdego z nich, a następnie ustawić wszystkie inne wątki, aby nie miały powinowactwa do tych 2 rdzeni. Aby to zrobić, musisz „

reirab
źródło
1

Każdy kod używający blokad z dowolną zauważalną ilością rywalizacji o blokadę będzie działał strasznie (do tego stopnia, że ​​w przypadku aplikacji takich jak gra można powiedzieć „nie działa” ), jeśli liczba wątków przekroczy liczbę rdzeni.

Wyobraź sobie na przykład wątek producenta wysyłający zadania do kolejki obsługującej 4 wątki konsumenckie. Istnieją tylko dwa rdzenie:

Producent próbuje uzyskać blokadę, ale jest ona utrzymywana przez konsumenta działającego na drugim rdzeniu. Dwa rdzenie wykonują blokadę, gdy producent kręci się, czekając na zwolnienie blokady. To już jest złe, ale nie tak złe, jak się da.
Niestety, wątek konsumencki jest u kresu swojego czasu kwantowego, więc jest zapobiegany i planowany jest inny wątek konsumencki. Próbuje złapać zamek, ale oczywiście zamek jest zajęty, więc teraz dwa rdzenie wirują i czekają na coś, co nie może się zdarzyć.
Wątek producenta osiąga koniec przedziału czasowego i jest zapobiegany, budzi się inny konsument. Znowu dwóch konsumentów czeka na zwolnienie blokady, i to się nie stanie przed upływem dwóch kolejnych kwantów.
[...] Wreszcie konsument trzymający blokadę zwolnił blokadę. Jest natychmiast brany przez każdego, kto obraca się na drugim rdzeniu. Istnieje 75% szans (3 do 1), że to kolejny wątek konsumencki. Innymi słowy, jest 75% prawdopodobne, że producent nadal jest zawieszony. Oczywiście oznacza to, że konsumenci również zwlekają. Bez uciążliwych zadań producenta nie mają nic do roboty.

Zauważ, że działa to w zasadzie z każdym rodzajem blokady, nie tylko spinlockami - ale dewastujący efekt jest znacznie bardziej widoczny w przypadku spinlocków, ponieważ procesor utrzymuje cykle spalania, podczas gdy nic nie osiąga.

Teraz wyobraź sobie, że oprócz powyższego jakiś programista miał genialny pomysł, aby użyć dedykowanego wątku z powinowactwem ustawionym na pierwszy rdzeń, więc RDTSC da wiarygodne wyniki na wszystkich procesorach (i tak nie będzie, ale niektórzy tak myślą).

Damon
źródło
Dlatego dobre bloki spinowe obniżają klasę na inne typy zamków po krótkim czasie, a nawet lepsze robią to bardzo szybko, jeśli poprzednie zastosowania tej samej blokady musiały zostać obniżone.
Ian
-1

Jeśli rozumiem, o co pytasz, jest to możliwe, ale jest to bardzo, bardzo zła rzecz.

Kanonicznym przykładem tego, co opisujesz, byłoby utrzymanie licznika, który jest zwiększany przez wiele wątków. Nie wymaga to prawie nic w zakresie mocy obliczeniowej, ale wymaga starannej koordynacji między wątkami. Tak długo, jak narasta tylko jeden wątek naraz (w rzeczywistości jest to odczyt, po którym następuje dodanie, po którym następuje zapis), jego wartość zawsze będzie poprawna. Wynika to z faktu, że jeden wątek zawsze odczytuje poprawną wartość „poprzednia”, dodaje jeden i zapisuje prawidłową wartość „następną”. Weź dwa wątki do akcji jednocześnie i oba będą czytać tę samą „poprzednią” wartość, uzyskaj ten sam wynik z przyrostu i zapisz tę samą „następną” wartość. Licznik zostanie skutecznie zwiększony tylko raz, mimo że dwa wątki myślą, że każdy to zrobił.

Ta zależność między czasem a poprawnością jest tym, co informatyka nazywa wyścigiem .

Często eliminuje się warunki wyścigu, stosując mechanizmy synchronizacji, aby upewnić się, że wątki chcące operować na kawałku współdzielonych danych muszą się połączyć w celu uzyskania dostępu. Licznik opisany powyżej może w tym celu użyć blokady odczytu i zapisu .

Bez dostępu do wewnętrznego projektu Dragon Age: Inkwizycja wszystko, co można zrobić, to spekulować na temat tego, jak się zachowuje. Ale spróbuję na podstawie kilku rzeczy, które widziałem w moim własnym doświadczeniu:

Możliwe, że program jest oparty na czterech dostrojonych wątkach, więc wszystko działa, gdy wątki działają prawie nieprzerwanie na ich własnych rdzeniach fizycznych. „Dostrajanie” może polegać na przestawianiu kodu lub wstawianiu snu w strategiczne miejsca, aby złagodzić błędy spowodowane przez rasę, które pojawiły się podczas opracowywania. Ponownie, to wszystko przypuszczenie, ale widziałem, że warunki wyścigowe „rozwiązały się” w ten sposób więcej razy, niż chciałbym policzyć.

Uruchomienie takiego programu na czymkolwiek mniej zdolnym niż środowisko, dla którego został dostrojony, wprowadza zmiany czasowe, które są wynikiem tego, że kod nie działa tak szybko lub, co bardziej prawdopodobne, przełącza kontekst. Przełączanie kontekstu zachodzi w sposób fizyczny (tj. Fizyczne rdzenie procesora przełączają się między pracą, którą wstrzymują jego rdzenie logiczne) i logiczną (tj. System operacyjny w CPU przypisuje pracę do rdzeni) na różne sposoby, ale jest to znacząca rozbieżność od będzie „oczekiwanym” czasem wykonania. To może wywołać złe zachowanie.

Jeśli Dragon Age: Inkwizycja nie wykona prostego kroku, aby upewnić się, że przed kontynuowaniem jest wystarczająca liczba rdzeni fizycznych, to wina EA. Prawdopodobnie spędzają małą fortunę na polowaniu na połączenia i wiadomości e-mail od osób, które próbowały uruchomić grę na zbyt małym sprzęcie.

Blrfl
źródło
1
Niektórzy gracze twierdzą, że jest to spowodowane DRM działającym na 2 rdzeniach, a rzeczywista gra działa również na 2. Gdy wątki DRM i gry działają na tym samym rdzeniu, zostaje to pomieszane. Ale to nie brzmi dla mnie poprawnie, może to być krótka historia stworzona przez gracza, który nie wie dużo o architekturze SW lub HW.
uylmz
4
warunki wyścigowe naprawdę nie mają wiele wspólnego z liczbą rdzeni, -1 ... maszyna z jednym rdzeniem z wieloma wirtualnymi wątkami może mieć warunki wyścigu całkowicie zależne od techniki dzielenia czasu środowiska wykonawczego, lub system wielu rdzeni może uniknąć wszystkich warunków wyścigu zależnych o tym, jak surowe jest to z operacjami membar ...
Jimmy Hoffa
1
@ Reek: Bez dogłębnej wiedzy o tym, jak działa program, wszystko jest zgadywaniem. Dwa rdzenie do wykonania DRM wydają mi się trochę przesadne.
Blrfl,
1
@JimmyHoffa: Nie zgadzam się. Warunek wyścigu jest nadal warunkiem wyścigu, nawet jeśli nie powoduje niepożądanych zachowań. Liczba rdzeni może wpływać na to, czy takie zachowanie się zdarza, o co pytał pytający, ale nie cytowałem tego jako jedynej zmiennej.
Blrfl,
-1

System Windows ma wbudowaną funkcjonalność: funkcja GetLogicalProcessorInformation znajduje się w interfejsie API systemu Windows . Możesz wywołać go ze swojego programu, aby uzyskać informacje na temat rdzeni, rdzeni wirtualnych i hiperwątkowości.

Tak więc odpowiedź na twoje pytanie brzmi: tak.

Pieter B.
źródło
3
Nie pytam: „Czy nie mogę znaleźć rdzeni z kodu?” ... Taki kod będzie niewłaściwy (zmusza do zakupu droższego procesora do uruchomienia programu - bez potrzeby korzystania z mocy obliczeniowej).
uylmz
3
Ta funkcja daje znacznie więcej informacji niż tylko „surową liczbę rdzeni”. Dzięki tym informacjom możesz odjąć rdzenie fizyczne, rdzenie logiczne i wiele innych. Jeśli możesz to odliczyć, możesz napisać oprogramowanie, które wykorzysta te informacje. W dobry lub zły sposób (program awarii, gdy widzisz 4 rdzenie, ale mniej niż 4 rdzenie fizyczne).
Pieter B
1
Może to działać w systemie Windows, ale co z OSX / Linux / iOS / Android / itp.? Chociaż odnosi się do gry jako instancji, w której takie zachowanie jest widoczne (a naturalną korelacją byłoby Windows = Gaming), nie wydaje się, aby była to prośba dotycząca konkretnej gry.
Robert
W przypadku gier takich jak Dragon Age omawiane systemy to Windows / XBox / PS4.
Gort the Robot
Linux ma /proc/cpuinfoi sysconf(_SC_NPROCESSORS_ONLN)(ten ostatni jest wymieniony w POSIX). Korzystanie z informacji w celu wymuszenia minimalnego progu wydajności jest jednak dość złą formą.
cHao