Perché un programma richiederebbe un numero minimo specifico di core della CPU?


55

È possibile scrivere codice (o software completo, anziché un pezzo di codice) che non funzionerà correttamente se eseguito su una CPU che ha meno di N numero di core? Senza verificarlo esplicitamente e fallire di proposito:

SE (noOfCores <4) ALLORA non funziona correttamente di proposito

Sto osservando i requisiti minimi di sistema di un gioco ( Dragon Age: Inquisition ) e indica un minimo di una CPU a quattro core. Molti giocatori affermano che NON funziona su CPU a due core e ANCHE su Intel Core i3 con due core fisici e due logici. E NON è un problema di potenza di calcolo.

Da quanto ho capito, i thread sono completamente isolati dalla CPU dal sistema operativo poiché non è possibile farlo.

Giusto per chiarire le cose:

NON sto chiedendo "Posso scoprire il numero di core della CPU dal codice e fallire di proposito?" ... Tale codice sarebbe mal intenzionato (ti costringe ad acquistare una CPU più costosa per eseguire un programma - senza la necessità di potenza computazionale). Sto chiedendo che il tuo codice, ad esempio, abbia quattro thread e fallisca quando due thread vengono eseguiti sullo stesso core fisico (senza controllare esplicitamente le informazioni di sistema e volutamente fallire) .

In breve, può esistere un software che richiede più core, senza la necessità di ulteriore potenza di elaborazione proveniente da più core? Richiederebbe solo N nuclei fisici separati.


11
Se leggi attentamente la mia domanda vedrai che non stanno facendo la stessa cosa.
Uylmz,

21
Poiché il numero di core può essere recuperato, può essere confrontato con N, e se quel confronto viene valutato come vero, il codice può fare tutto l'inferno che vuole, incluso ma non limitato a comportarsi in modi non pubblicizzati. Qual'è la tua domanda?

3
Sei sicuro che il problema sia realmente e direttamente correlato al numero di core? Forse il gioco citato è parzialmente basato su una funzione (correttamente) fornita dalla CPU con almeno 4 core?
mgoeminne,

25
Si noti che i "requisiti minimi di sistema" sono spesso "requisiti minimi di sistema per funzionare con prestazioni accettabili", in particolare con i giochi. È molto probabile che Dragon Age potesse, in teoria, funzionare su un singolo core box, ma se lo facessi, mostrerebbe enormi cadute di frame. Quindi richiedono questo numero di core non per costringerti ad acquistare hardware, ma per evitare lamentele di qualità da parte degli utenti di hardware di fascia bassa.
Gort the Robot

3
@Sebb: penso che ti piaccia qualcosa: se 4 core fisici si correlano con avere più cache di 2 logici / 4 fisici, allora il gioco potrebbe naturalmente soffocare su macchine 2x2 senza colpire i loro limiti di potenza di elaborazione perché manca tutta la cache tempo. Il test sarebbe quello di trovare una CPU con 2x2 core e un sacco di cache, o 4 core e poca cache, e vedere cosa succede.
Steve Jessop,

Risposte:


45

Potrebbe essere possibile farlo "per caso" con un uso incurante dell'affinità di base. Considera il seguente pseudocodice:

  • inizia una discussione
  • in quel thread, scopri su quale core è in esecuzione
  • imposta la sua affinità CPU su quel core
  • iniziare a fare qualcosa di intensivamente computazionale / loop per sempre

Se ne avvii quattro su una CPU a due core, allora qualcosa va storto con l'impostazione di affinità del core o finisci con due thread che registrano i core disponibili e due thread che non vengono mai programmati. Non ha mai chiesto esplicitamente quanti core ci sono in totale.

(Se si dispone di thread con esecuzione prolungata, l'impostazione dell'affinità della CPU generalmente migliora la velocità effettiva)

L'idea che le società di giochi "costringano" le persone ad acquistare hardware più costoso senza una buona ragione non è molto plausibile. Può solo perdere loro i clienti.

Modifica: questo post ha ora 33 voti positivi, il che è parecchio dato che si basa su congetture istruite!

Sembra che la gente abbia DA: I da eseguire, malamente, su sistemi dual-core: http://www.dsogaming.com/pc-performance-analyses/dragon-age-inquisition-pc-performance-analysis/ Quell'analisi afferma che la situazione migliora notevolmente se l'hyperthreading è attivato. Dato che HT non aggiunge più unità o cache di emissione di istruzioni, consente semplicemente l'esecuzione di un thread mentre un altro si trova in uno stallo della cache, il che suggerisce fortemente che è collegato esclusivamente al numero di thread.

Un altro poster afferma che la modifica dei driver grafici funziona: http://answers.ea.com/t5/Dragon-Age-Inquisition/Working-solution-for-Intel-dual-core-CPUs/td-p/3994141 ; dato che i driver grafici tendono ad essere un miserabile alveare di feccia e malvagità, questo non è sorprendente. Un noto set di driver aveva una modalità "corretta e lenta" rispetto a "veloce e errata" che era selezionata se chiamata da QUAKE.EXE. È del tutto possibile che i driver si comportino diversamente per diversi numeri di CPU apparenti. Forse (tornando alla speculazione) viene utilizzato un meccanismo di sincronizzazione diverso. Uso improprio di spinlock ?

"L'uso improprio di primitive di blocco e sincronizzazione" è una fonte molto comune di bug. (Il bug che dovrei guardare al lavoro mentre scrivo questo è "crash se la modifica delle impostazioni della stampante allo stesso tempo al termine del lavoro di stampa").

Modifica 2: i commenti menzionano il SO che tenta di evitare la fame di thread. Nota che il gioco potrebbe avere un proprio quasi-scheduler interno per assegnare lavoro ai thread e ci sarà un meccanismo simile nella stessa scheda grafica (che è effettivamente un sistema multitasking a sé stante). Le probabilità di un bug in uno di questi o l'interazione tra di loro sono piuttosto alte.

www.ecsl.cs.sunysb.edu/tr/ashok.pdf (2008) è una tesi di laurea su una migliore pianificazione per le schede grafiche che menziona esplicitamente che usano normalmente la pianificazione primo arrivato, che è facile da implementare in sistemi non preventivi. La situazione è migliorata? Probabilmente no.


1
Sì, ci sono due parti per rispondere a questa domanda: l'affinità della CPU consente di codificare qualcosa che lo renderebbe un requisito tecnico in Windows, la risposta alternativa è che i sistemi in tempo reale possono decisamente richiedere tali cose. +1 per essere l'unica persona a menzionare l'affinità della CPU che è davvero il colpevole più probabile per ciò che viene chiesto qui.
Jimmy Hoffa,

3
Cosa può andare storto se si imposta l'affinità sul core corrente? Con il multitasking preventivo verrà pianificato il thread di attesa a meno che quello attuale non abbia la massima priorità possibile ("realtime" in Windows). Vedrei un altro scenario: a ciascuno dei 4 thread viene assegnata un'affinità definita staticamente di 1,2,4,8, nel qual caso gli ultimi due thread non verranno mai programmati (anche se non sono sicuro se l'impostazione dell'affinità su efficace lo zero avrà successo).
Ruslan,

@Ruslan Forse provando a impostare un'affinità non valida si bloccherà in primo luogo l'applicazione?
Luaan,

1
@Luaan non è un'operazione rischiosa che porta a un incidente. Il massimo che mi aspetterei è un errore restituito dal sistema operativo. Ho appena controllato, in Linux ricevo l'errore "Argomento non valido". Non so cosa direbbe Windows.
Ruslan,

@Ruslan Ogni sistema operativo principale da oltre un decennio ha incluso il codice per evitare la fame di thread (di solito aumentando la priorità di un thread dopo che non è stato eseguito per un tempo sufficiente).
Voo

34

Potrebbe essere necessario disporre di 4 core poiché l'applicazione esegue quattro attività in thread paralleli e si aspetta che finiscano quasi contemporaneamente.

Quando ogni thread viene eseguito da un core separato e tutti i thread hanno lo stesso carico di lavoro computazionale, è molto probabile (ma tutt'altro che garantito) terminare all'incirca allo stesso tempo. Ma quando due thread vengono eseguiti su un core, i tempi saranno molto meno prevedibili perché il core cambierà continuamente contesto tra i due thread.

I bug che si verificano a causa di tempi di thread imprevisti vengono definiti " condizioni di gara ".

Nel contesto dello sviluppo del gioco, un'architettura plausibile con questo tipo di problema potrebbe essere quella in cui diverse funzionalità del gioco sono simulate in tempo reale da diversi thread della CPU. Quando ciascuna funzione viene eseguita su un proprio core, vengono simulati all'incirca alla stessa velocità. Ma quando due funzioni girano su un core, entrambe saranno simulate solo la metà del resto del mondo di gioco, il che potrebbe causare comportamenti strani.

Si noti che un'architettura software che dipende da thread indipendenti in esecuzione con temporizzazioni specifiche è estremamente fragile e indica una pessima comprensione della programmazione concorrente. In quasi tutte le API multithreading sono disponibili funzionalità per sincronizzare esplicitamente i thread e prevenire questo tipo di problemi.


11
Ma ogni gioco ha una fragile dipendenza dalla capacità di completare tutti i calcoli per il fotogramma successivo in tempo per renderlo con una frequenza ragionevole. Anche se i tuoi 4 thread sono sincronizzati correttamente, potrebbe essere impossibile renderli in modo tempestivo e non ci sono vantaggi in un gioco che è computazionalmente corretto ma non giocabile a causa di ritardo e balbuzie.
Inutile

1
@Inutile: non è proprio vero. Ad esempio, è possibile buffer frame o dati di simulazione per nascondere eventuali balbuzie e esistono progetti concorrenti più coerenti. Ottenere tutta la tua elaborazione in X time e richiedere la sincronizzazione esatta di tale elaborazione sono questioni diverse.
DeadMG

23
"un'architettura software che dipende da thread indipendenti in esecuzione con tempistiche specifiche è estremamente fragile" Questo è esattamente il motivo per cui non riesco a immaginare un gioco che non funziona affatto con 2 core, ma funziona in modo affidabile con 4 core. Anche con 4 core, i tempi saranno imprevedibili, quindi si verificherebbero anche le condizioni di gara, anche se meno frequentemente.
svick

8
@svick ovviamente. Ma la domanda si pone "è possibile?" non "è sano?"
user253751

5
Qualsiasi codice con questo tipo di "condizioni di gara" è completamente rotto , indipendentemente da quanti core lo esegui. (Soprattutto dal momento che non c'è assolutamente alcuna garanzia su cos'altro è in esecuzione sul sistema.) Dubito seriamente che questa sia la causa, data la facilità con cui potrebbe inciampare il gioco anche su un sistema hexacore ...
DevSolar

16

È improbabile che questi "requisiti minimi" rappresentino qualcosa al di sotto del quale il gioco non funzionerà. Molto più probabile è che rappresentino qualcosa al di sotto del quale il gioco non funzionerà con prestazioni accettabili. Nessuna società di gioco vuole trattare con molti clienti che si lamentano di prestazioni scadenti quando lo eseguono su una scatola single core da 1 Ghz, anche se il software potrebbe funzionare tecnicamente. Quindi probabilmente progettano deliberatamente di fallire duramente su scatole con meno core di quanto darebbe loro prestazioni accettabili.

Una metrica importante nelle prestazioni di gioco è la frequenza dei fotogrammi. In genere funzionano a 30 o 60 frame al secondo. Ciò significa che il motore di gioco deve eseguire il rendering della vista corrente dallo stato del gioco in un determinato periodo di tempo. Per ottenere 60 fps, ha solo poco più di 16 msec per farlo. I giochi con grafica di fascia alta sono estremamente legati alla CPU e quindi c'è un enorme vantaggio tra il tentativo di spingere una qualità superiore (che richiede più tempo) e la necessità di rimanere in questo budget di tempo. Pertanto, il budget di tempo per ciascun frame è estremamente limitato.

Poiché il budget di tempo è limitato, lo sviluppatore desidera idealmente l'accesso esclusivo a uno o più core. Probabilmente vogliono anche essere in grado di fare le loro cose di rendering in un core, esclusivamente, poiché è ciò che deve essere fatto con quel budget di tempo, mentre altre cose, come il calcolo dello stato mondiale, avvengono in un processo separato dove non lo faranno intromettersi.

Potresti, in teoria, stipare tutto questo su un unico core, ma poi tutto diventa molto più difficile. All'improvviso devi assicurarti che tutto ciò che riguarda lo stato del gioco avvenga abbastanza velocemente e permetta il rendering. Non puoi semplicemente farli due thread software perché non c'è modo di far capire al sistema operativo "il thread A deve completare X quantità di lavoro in 16 msec indipendentemente da quale thread B fa".

Gli sviluppatori di giochi non hanno interesse a farti acquistare nuovo hardware. Il motivo per cui hanno requisiti di sistema è che non vale la pena sostenere il costo del supporto di macchine di fascia bassa.


Anche se questo è vero, succede che puoi acquistare hardware dual-core abbastanza potente da poter ottenere di più in un determinato intervallo di tempo rispetto all'hardware quad core descritto nelle specifiche minime. Perché il fornitore non dovrebbe elencare tale hardware come accettabile, una decisione che può solo perdere loro le vendite?
Jules

4
La cosa da confrontare non è 2 vs 4 core. È essenzialmente 1 contro 3 core, poiché la CPU # 0 sarà praticamente ancorata al driver grafico e ai DPC. Ci sono anche effetti significativi sulla cache e sulla migrazione se si annulla l'iscrizione di una CPU con diversi tipi di attività nel tipico sistema di lavoro di un gioco moderno. Il requisito è lì perché Frostbite (DA: il motore di I) è progettato da zero con un'accurata messa a punto che richiede un numero particolare di core.
Lars Viklund,

6
@LarsViklund Sembra che tu sappia più dettagli di chiunque altro qui. Hai mai pensato di mettere insieme una risposta?
Gort the Robot

1
"È improbabile che questi" requisiti minimi "rappresentino qualcosa al di sotto del quale il gioco non funzionerà. Molto più probabile è che rappresentino qualcosa al di sotto del quale il gioco non funzionerà con prestazioni accettabili." - Intel G3258 è un potente processore dual core ampiamente utilizzato dai giocatori che è in grado di eseguire giochi uguali o più ricchi di risorse rispetto a Dragon Age Inquisition, ma molti giocatori riferiscono che il gioco non funziona su di esso.
uylmz,

2
@Reek Sono dubbioso che un utente finale possa facilmente dire quanto sia intensivo il ricorso alle risorse rispetto a un altro gioco.
Gort the Robot

9

Tre thread in tempo reale che non dormono mai e un altro thread. Se sono presenti meno di quattro core, il quarto thread non verrà mai eseguito. Se il quarto thread deve comunicare con uno dei thread in tempo reale per il completamento del thread in tempo reale, il codice non terminerà con meno di quattro core.

Ovviamente se i thread in tempo reale sono in attesa di qualcosa che non consente loro di dormire (come uno spinlock), il progettista del programma ha rovinato tutto.


1
Probabilmente, quando un'applicazione utente richiede in primo luogo thread in tempo reale, il designer ha
rovinato

2
L'ho fatto. Mezzo milione di righe di codice. Un caso che utilizza circa 300 righe. Il thread in tempo reale trascorre la maggior parte del tempo in attesa di input in modo da poter timestamp dell'input e passarlo a un thread con priorità inferiore.
Joshua,

2
@Luaan Per la maggior parte delle applicazioni sono d'accordo con te, ma i giochi sono una bestia diversa, così come le applicazioni integrate. In entrambi i casi, la preoccupazione di giocare bene con altre applicazioni simultanee va in gran parte fuori dalla finestra a favore delle prestazioni.
reirab

Anche se non sarebbe particolarmente efficiente, questo scenario non porterebbe a deadlock - l'inversione prioritaria si occuperebbe di esso (supponendo che ogni programmatore a metà strada decente in qualsiasi sistema operativo principale dell'ultimo decennio)
Voo

2
@Joshua > Windows non sa quale sia l'inversione di priorità. Che cosa? support.microsoft.com/kb/96418 , msdn.microsoft.com/en-us/library/windows/desktop/ms684831.aspx . Inoltre, inversione di priorità è il termine che descrive il problema , non una soluzione (@Voo).
Bob,

3

Innanzitutto i thread del software non hanno nulla a che fare con i thread dell'hardware e sono spesso confusi. I thread del software sono pezzi di codice che possono essere inviati ed eseguiti da soli nel contesto del processo. I thread hardware sono gestiti principalmente dal sistema operativo e vengono inviati al core del processore quando si parla di programmi regolari. Questi thread hardware vengono inviati in base al carico; il dispatcher di thread hardware si comporta più o meno come un bilanciamento del carico.

Tuttavia, quando si tratta di giochi, in particolare giochi di fascia alta, a volte i thread hardware sono gestiti dal gioco stesso o il gioco indica al dispatcher di thread hardware cosa fare. Questo perché ogni attività o gruppo di attività non ha la stessa priorità di un normale programma. Poiché l'età del drago proviene da uno studio di gioco di fascia alta che utilizza motori di gioco di fascia alta, posso immaginare che utilizzi la spedizione "manuale" e quindi il numero di core diventa un requisito di sistema minimo. Qualsiasi programma si arresterebbe in modo anomalo quando invio un pezzo di codice al terzo core fisico in esecuzione su una macchina con solo 1 o 2 core.


Questo. Ricorda che dire "check no of core" significa che un'azienda sta realizzando il suo prodotto software in un modo specifico per costringere gli utenti ad acquistare hardware più costoso (che sarebbe mal progettato).
Uylmz,

2
Questi problemi esistono fino a quando ci sono giochi per PC. All'inizio avevamo 486dx e 486sx, successivamente MMX e non-MMX Pentium, core e non-core e oggi abbiamo requisiti n-core. Questo è uno dei motivi per cui le console esistono ancora.
dj bazzie wazzie,

4
Hai un riferimento per i giochi che si occupano autonomamente della programmazione della CPU? Per quanto ne sapevo, questo non è direttamente possibile in Windows, almeno non in un modo che fallirebbe nel modo che suggerisci.
Jules

2
@djbazziewazzie in realtà Windows fornisce un API per fare proprio questo, ovvero impostare un thread per usare sempre lo stesso core; questo si chiama affinità di thread e non consente di selezionare manualmente quale parte di codice viene eseguita dove e quando e non può causare un errore di sistema come suggerito (il sistema ignorerà una richiesta per impostare l'affinità su un core inesistente e continua a programmare il thread su qualsiasi core quando diventa disponibile. Sono abbastanza sicuro che questo sia l'id di Tech e non equivale a "gestire i thread hardware".
Jules

1
@djbazziewazzie Sembra anche che tu fraintenda il punto di Grand Central Dispatch, che non offre agli sviluppatori un maggiore controllo su come il loro codice è programmato su un core; infatti, il suo scopo è esattamente l'opposto: prendere la scelta di quanti thread creare e quale codice deve essere eseguito su quale thread dalle mani delle applicazioni in modo che possa essere ottimizzato per l'hardware disponibile a livello di sistema. La dipendenza dall'avere un certo numero di core è esattamente il tipo di problema che GCD è stato progettato per prevenire.
Jules

1

Dato che è possibile utilizzare la virtualizzazione per avere più core virtuali che fisici e il software non saprebbe che è in esecuzione su una virtualizzazione e invece penserebbe che abbia così tanti core fisici, direi che tale software non è possibile.

Vale a dire, non è possibile scrivere software che si fermerà sempre su meno di N core.

Come altri hanno sottolineato, ci sono soluzioni software che possono potenzialmente verificare, specialmente se il sistema operativo e il codice utilizzati hanno poca protezione dalle condizioni di competizione quando N processi sono eseguiti su processori <N. Il vero trucco è il codice che fallirà quando hai meno di N processori ma non fallirà quando hai N processori ma hai un sistema operativo che può assegnare lavoro a meno di N processori.


1

È possibile che ci siano tre thread che fanno qualcosa (generano sfondi o generano movimenti NPC) e passano gli eventi a un quarto, che dovrebbe aggregare / filtrare gli eventi e aggiornare il modello di vista. Se il quarto thread non ottiene tutti gli eventi (perché non è pianificato su un core), il modello di visualizzazione non viene aggiornato correttamente. Questo può accadere solo sporadicamente, ma quei core devono essere disponibili in qualsiasi momento. Questo potrebbe spiegare perché non si vede sempre un elevato utilizzo della CPU, ma il gioco non funziona comunque correttamente.


1
In uno scenario del genere il gioco fallirebbe anche casualmente quando si pianificavano l'esecuzione dei servizi in background, il che è abbastanza frequente sulla maggior parte dei pc.
Jules

1

Penso che Joshua stia seguendo la strada giusta, ma non per giungere alla sua conclusione.

Supponiamo di avere un'architettura in cui ci sono tre thread che sono scritti per fare il più possibile - quando finiscono quello che stanno facendo lo fanno di nuovo. Per migliorare le prestazioni, questi thread non rilasciano il controllo per nulla: non vogliono rischiare il ritardo dall'utilità di pianificazione di Windows. Fintanto che ci sono 4 o più core, questo funziona bene, se non ci riesce fallisce male.

In generale, si tratterebbe di una cattiva programmazione, ma i giochi sono un'altra cosa: quando ti trovi di fronte a una scelta tra un design inferiore su tutto l'hardware o un design superiore su un hardware sufficientemente buono o un guasto su un hardware inferiore, gli sviluppatori di solito scelgono per richiedere l'hardware.


Di solito non è possibile scrivere un thread che non cederà il controllo ad altri thread. Tutti i moderni sistemi operativi non RTOS utilizzano il multitasking preventivo, il che rende intenzionalmente impossibile per un thread (modalità utente) non rilasciare il controllo di un determinato core. I thread del kernel, ovviamente, sono una questione diversa.
reirab

@reirab Potenzia la sua priorità.
Loren Pechtel,

@Loren Non cambia il fatto che lo scheduler continua a smettere di funzionare, il che significa che devi condividere il tempo con altri thread con la stessa priorità e lo scheduler che aumenta la priorità dei thread affamati. Non puoi farlo sui normali sistemi operativi e, anche se potessi, i giochi non sarebbero certamente un'applicazione accettabile per farlo.
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?

Assolutamente. L'uso di thread in tempo reale sarebbe un buon esempio di una situazione in cui questo non è solo possibile, ma il modo desiderato (e spesso l'unico modo corretto) per portare a termine il lavoro. Tuttavia, i thread in tempo reale sono generalmente limitati al kernel del sistema operativo, in genere per i driver che devono essere in grado di garantire che un evento hardware di qualche tipo venga gestito entro un determinato periodo di tempo. Non dovresti avere thread in tempo reale nelle normali applicazioni utente e non sono sicuro che sia anche possibile averne uno in un'applicazione Windows in modalità utente. Generalmente, i sistemi operativi rendono intenzionalmente impossibile farlo dalla terra dell'utente proprio perché consente a una determinata applicazione di assumere il controllo del sistema.

Per quanto riguarda le applicazioni utente-terra: il tuo presupposto che il controllo di un determinato numero di thread per essere eseguito sia necessariamente intenzionale non è corretto. Ad esempio, potresti avere 2 attività di lunga durata, che richiedono prestazioni elevate e che richiedono un core. Indipendentemente dalla velocità del core della CPU, la condivisione di un core con altri thread potrebbe essere un peggioramento delle prestazioni grave e inaccettabile a causa del thrashing della cache e delle normali penalità dovute al cambio di thread (che sono piuttosto sostanziali). In questo caso, sarebbe perfettamente ragionevole, specialmente per un gioco, impostare ciascuno di questi thread in modo che abbia un'affinità solo su un core particolare per ciascuno di essi e quindi impostare tutti gli altri thread in modo che non abbiano affinità su quei 2 core. Per fare ciò, però,


1

Qualsiasi codice che utilizza spinlock con una notevole quantità di contesa di lock funzionerà terribilmente (nella misura in cui - per un'applicazione come un gioco - puoi dire "non funziona" ) se il numero di thread supera il numero di core.

Immagina ad esempio un thread del produttore che invia attività a una coda che serve 4 thread consumer. Esistono solo due core:

Il produttore cerca di ottenere lo spinlock, ma è trattenuto da un consumatore che gira sull'altro core. I due core eseguono la sequenza di blocchi mentre il produttore gira, in attesa di rilasciare il blocco. Questo è già negativo, ma non così grave.
Sfortunatamente, il thread del consumatore è alla fine del suo tempo quantico, quindi è anticipato e viene pianificato un altro thread del consumatore. Cerca di afferrare il lucchetto, ma ovviamente il lucchetto viene preso, quindi ora due nuclei ruotano e aspettano qualcosa che non può accadere.
Il thread del produttore raggiunge la fine della sua fascia oraria ed è anticipato, un altro consumatore si sveglia. Ancora una volta, due consumatori stanno aspettando il rilascio di un blocco, e non accadrà prima che siano trascorsi altri due quanti quantum.
[...] Finalmente il consumatore che aveva in mano lo spinlock ha rilasciato il blocco. Viene immediatamente preso da chiunque gira sull'altro nucleo. C'è una probabilità del 75% (da 3 a 1) che si tratti di un altro thread di consumo. In altre parole, è probabile che il 75% del produttore sia ancora bloccato. Naturalmente questo significa che anche i consumatori si fermano. Senza il produttore che sopporta compiti, non hanno nulla da fare.

Si noti che questo funziona in linea di principio con qualsiasi tipo di blocco, non solo con gli spinlock, ma l'effetto devastante è molto più evidente con gli spinlock perché la CPU continua a bruciare i cicli mentre non ottiene nulla.

Ora immagina che oltre a quanto sopra alcuni programmatori abbiano avuto la brillante idea di usare un thread dedicato con affinità impostata sul primo core, quindi RDTSC darà risultati affidabili su tutti i processori (non lo farà comunque, ma alcune persone lo pensano).


Questo è il motivo per cui i buoni spinlock eseguono il downgrade ad altri tipi di blocco dopo un breve periodo di tempo, e anche quelli migliori lo fanno molto più rapidamente se gli usi passati dello stesso blocco hanno dovuto eseguire il downgrade.
Ian,

-1

Se capisco cosa stai chiedendo, è possibile, ma è una cosa molto, molto brutta.

L'esempio canonico di ciò che stai descrivendo sarebbe il mantenimento di un contatore che viene incrementato da più thread. Ciò non richiede quasi nulla in termini di potenza di calcolo, ma richiede un attento coordinamento tra i thread. Finché un solo thread alla volta esegue un incremento (che in realtà è una lettura seguita da un'aggiunta seguita da una scrittura), il suo valore sarà sempre corretto. Questo perché un thread leggerà sempre il valore "precedente" corretto, ne aggiungerà uno e scriverà il valore "successivo" corretto. Ottieni due thread nell'azione contemporaneamente ed entrambi leggono lo stesso valore "precedente", ottengono lo stesso risultato dall'incremento e scrivono lo stesso valore "successivo". Il contatore sarà effettivamente aumentato solo una volta, anche se due thread pensano di averlo fatto ciascuno.

Questa dipendenza tra tempismo e correttezza è ciò che l'informatica chiama una condizione di razza .

Le condizioni di gara vengono spesso evitate utilizzando i meccanismi di sincronizzazione per assicurarsi che i thread che desiderano operare su una parte di dati condivisi debbano mettersi in fila per l'accesso. Il contatore sopra descritto potrebbe usare un blocco lettura-scrittura per questo.

Senza accesso al design interno di Dragon Age: Inquisition , tutto ciò che chiunque può fare è speculare sul perché si comporti in questo modo. Ma proverò sulla base di alcune cose che ho visto fare nella mia esperienza:

È possibile che il programma si basi su quattro thread che sono stati sintonizzati in modo che tutto funzioni quando i thread vengono eseguiti per lo più ininterrottamente sui propri core fisici. La "messa a punto" potrebbe presentarsi sotto forma di riorganizzazione del codice o inserimento di sleep in luoghi strategici per mitigare i bug indotti dalle condizioni di gara che sono emersi durante lo sviluppo. Ancora una volta, questa è tutta una congettura, ma ho visto le condizioni di gara "risolte" in quel modo più volte di quanto mi importi.

L'esecuzione di un programma in questo modo su qualcosa di meno capace rispetto all'ambiente per il quale è stato messo a punto introduce cambiamenti di temporizzazione che sono il risultato del fatto che il codice non viene eseguito più rapidamente o, più probabilmente, dei cambi di contesto. I cambi di contesto avvengono in modo fisico (ovvero i nuclei fisici della CPU stanno cambiando tra il lavoro svolto dai suoi core logici) e logici (ovvero, il sistema operativo sulla CPU sta assegnando lavoro ai core), ma l'una o l'altra è una significativa divergenza rispetto a ciò sarebbe il tempismo di esecuzione "previsto". Ciò può far emergere comportamenti scorretti.

Se Dragon Age: Inquisition non fa il semplice passo per assicurarsi che ci siano abbastanza nuclei fisici disponibili prima di procedere, è colpa di EA. Probabilmente stanno spendendo una piccola fortuna mettendo in campo le chiamate di supporto e le e-mail da parte di persone che hanno cercato di eseguire il gioco su hardware troppo piccolo.


1
Alcuni giocatori dicono che è causato dal DRM che gira su 2 core e il gioco vero e proprio funziona anche su 2. Quando DRM e i thread di gioco vengono eseguiti sullo stesso core, si incasina. Ma questo non sembra corretto per me, potrebbe essere una piccola storia inventata da un giocatore che non sa molto sull'architettura sw o hw.
Uylmz,

4
le condizioni di gara non hanno molto a che fare con il conteggio dei core, -1 ... una macchina single core con più thread virtuali può avere condizioni di gara totalmente dipendenti dalla tecnica del time runtime del runtime, oppure un sistema a molti core potrebbe evitare tutte le condizioni di gara dipendenti su quanto sia severo con le operazioni membar ...
Jimmy Hoffa,

1
@Reek: senza una profonda conoscenza di come funziona il programma, qualsiasi cosa è un'ipotesi. Due core da fare solo con il DRM mi sembrano un po 'eccessivi.
Blrfl,

1
@JimmyHoffa: non sono d'accordo. Una condizione di razza è ancora una condizione di razza anche quando non sta causando comportamenti indesiderati. Il conteggio dei core può influenzare se si verifica o meno quel comportamento, che è quello che l'interrogante ha chiesto, ma non l'ho citato come unica variabile.
Blrfl,

-1

Windows ha funzionalità integrate per questo: la funzione GetLogicalProcessorInformation è nell'API di Windows . Puoi chiamarlo dal tuo programma per ottenere informazioni su core, core virtuali e hyperthreading.

Quindi la risposta alla tua domanda sarebbe: Sì.


3
Non sto chiedendo "Posso scoprire no di core dal codice?" ... Tale codice sarà mal progettato (ti costringe ad acquistare una CPU più costosa per eseguire un programma - senza la necessità di potenza computazionale).
Uylmz,

3
Questa funzione fornisce molte più informazioni di un "numero di core" non elaborato. Con queste informazioni è possibile detrarre core fisici, core logici e altro. Se riesci a dedurlo, puoi scrivere software per utilizzare queste informazioni. In un modo buono o cattivo (programma di crash quando vedi 4 core ma meno di 4 core fisici).
Pieter B,

1
Questo può funzionare in Windows, ma per quanto riguarda OSX / Linux / iOS / Android / ecc.? Mentre fa riferimento a un gioco come un'istanza in cui viene visualizzato questo comportamento (e la correlazione naturale sarebbe Windows = Gioco), non sembra essere una richiesta specifica del gioco.
Robert

Per un gioco come Dragon Age, i sistemi in questione sono Windows / XBox / PS4.
Gort il robot il

Linux ha /proc/cpuinfoe sysconf(_SC_NPROCESSORS_ONLN)(quest'ultimo viene menzionato in POSIX). Tuttavia, l'utilizzo delle informazioni per imporre una soglia minima di prestazioni è ancora piuttosto negativo.
cHao,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.