Quanti sforzi dovremmo dedicare alla programmazione di più core?

12

Al giorno d'oggi i processori stanno acquisendo sempre più core, il che mi fa pensare ...

Dovremmo noi, programmatori, adattarci a questo comportamento e dedicare più impegno alla programmazione di più core?

In che misura dovremmo fare e ottimizzare questo? Filo? Affinità? Ottimizzazioni hardware? Qualcos'altro?

    
posta Tom Wijsman 24.09.2010 - 13:30
fonte

8 risposte

15

Non importa quanto sei bravo, è improbabile che tu possa trovare uno schema migliore di gestione dei thread ecc. rispetto ai team che sviluppano la lingua e il compilatore stai scrivendo il tuo codice .

Se hai bisogno che la tua applicazione sia multi-thread, crea i thread necessari e lascia che il compilatore e il sistema operativo facciano il loro lavoro.

È necessario essere consapevoli di come questi thread sono gestiti in modo da poter sfruttare al meglio le risorse. Non creare troppi thread è una cosa che mi viene in mente come esempio.

Devi anche essere a conoscenza di cosa sta succedendo (vedi il commento di Lorenzo) in modo da poter fornire suggerimenti per la gestione dei thread (o sovrascriverlo in casi particolari), ma avrei pensato che questi sarebbero stati pochi e distanti tra loro .

    
risposta data 24.09.2010 - 13:43
fonte
5

Sono un programmatore .NET e so che .NET ha un'astrazione di alto livello per il multithreading chiamato Task. Ti protegge dal dover sapere troppo su come fare il multithreading corretto contro il metallo. Suppongo che altre piattaforme di sviluppo attuali abbiano astrazioni simili. Quindi se hai intenzione di fare qualcosa con il multithreading, proverei a lavorare a quel livello se possibile.

Ora, alla domanda di dovresti ti interessa anche il multithreading nella tua particolare applicazione. La risposta a questa domanda dipende molto dall'applicazione che stai scrivendo. Se stai scrivendo un'applicazione che elabora su migliaia (o più) cose indipendenti, e questa elaborazione può essere eseguita in parallelo, quasi sicuramente otterrai un vantaggio dal multithreading. Tuttavia, se stai scrivendo una semplice schermata di immissione dei dati, il multithreading potrebbe non comprarti molto.

Per lo meno, devi occuparti del multithreading quando lavori su un'interfaccia utente. Non si desidera attivare un'operazione a esecuzione prolungata dall'interfaccia utente e farlo diventare insensibile perché si è compromesso il thread dell'interfaccia utente per eseguire tale operazione. Spegni un thread in background e fornisci almeno all'utente un pulsante Annulla in modo che non debbano attendere che venga completato se hanno commesso un errore.

    
risposta data 24.09.2010 - 13:51
fonte
5

Nella terra di Objective-C e Mac OS X e iOS, i framework (come molti altri) sono scritti per sfruttare questi aumenti nei core del processore e presentare allo sviluppatore un'interfaccia piacevole per utilizzarli.

Esempio su Mac OS X e iOS è la spedizione di Grand Central. Ci sono aggiunte a libc (credo) per facilitare il multi-threading basato sulla coda. Quindi i framework Cocoa e Foundation (tra gli altri) sono scritti sopra GCD, dando allo sviluppatore un facile accesso alle code di invio e threading con pochissimo codice della piastra della caldaia.

Molte lingue e framework hanno concetti simili.

    
risposta data 24.09.2010 - 16:00
fonte
5

La parte difficile è tutta nella suddivisione dell'algoritmo della CPU in blocchi di esecuzione che potrebbero essere sottoposti a thread.

Quindi, un thread che salta continuamente da un core ad un altro avrà delle penalità prestazionali (a causa della mancanza della cache della CPU di primo e secondo livello), specialmente nelle architetture in cui vengono impiegati due matrici fisiche distinte. In questo caso l'affinità thread-core è una buona cosa.

    
risposta data 24.09.2010 - 18:38
fonte
3

Siamo ora (ottobre 2010) in un momento di transizione immensa.

Oggi potremmo acquistare un desktop a 12 core.
Oggi potremmo acquistare una scheda di elaborazione core 448 (cercare NVidia Tesla).

Ci sono dei limiti a quanto noi sviluppatori possiamo lavorare ignorando gli ambienti tremendamente paralleli che i nostri programmi lavoreranno all'interno nel prossimo futuro.

I sistemi operativi, gli ambienti runtime e le librerie di programmazione possono fare solo così tanto.

In futuro, avremo bisogno di partizionare la nostra elaborazione in blocchi discreti per l'elaborazione indipendente, utilizzando astrazioni come il nuovo .NET "Task Framework".

Saranno comunque presenti dettagli come la gestione della cache e l'affinità, ma saranno la garanzia solo dell'applicazione ultra-performante. Nessuno stesso sviluppatore vorrà gestire questi dettagli manualmente su una macchina principale da 10k.

    
risposta data 09.10.2010 - 22:02
fonte
3

bene, dipende davvero da cosa stai sviluppando. la risposta, a seconda di ciò che si sta sviluppando, può variare da "è insignificante" a "è assolutamente fondamentale, e ci aspettiamo che tutti nel team abbiano una buona comprensione e l'uso di implementazioni parallele".

per la maggior parte dei casi, una solida comprensione e l'uso di lock, thread e task e pool di attività sarà un buon inizio quando è necessario il parallelismo. (varia da lang / lib)

aggiungi a ciò le differenze nei disegni che devi fare - per un multiprocessing non banale, devi spesso imparare diversi nuovi modelli di programmazione o strategie di parallelizzazione. in quel caso, il tempo di imparare, di fallire abbastanza volte per avere una solida comprensione e di aggiornare i programmi esistenti può prendere una squadra un anno (o più). una volta raggiunto quel punto, si spera (non si spera!) di non percepire o affrontare problemi / implementazioni come si fa oggi (a patto di non aver ancora effettuato quella transizione).

Un altro ostacolo è che stai effettivamente ottimizzando un programma per una certa esecuzione. se non ti viene dato molto tempo per ottimizzare i programmi, in realtà non ne trarrai vantaggio quanto dovresti. la parallelizzazione di alto livello (o ovvia) può migliorare la velocità percepita del programma con un piccolo sforzo, e questo è quanto molti team andranno oggi: "Abbiamo parallelizzato le parti più ovvie dell'app" - in alcuni casi va bene. il vantaggio di prendere il frutto basso appeso e utilizzando la semplice parallelizzazione sarà proporzionato al numero di nuclei? spesso, quando ci sono da due a quattro core logici ma non così spesso oltre. in molti casi, questo è un rendimento accettabile, considerato l'investimento nel tempo. questo modello parallelo è l'introduzione di molte persone per implementare buoni usi del parallelismo. è comunemente implementato usando iterazione in parallelo, attività esplicite, thread semplici o multitasking.

ciò che apprendi utilizzando questi banali modelli paralleli non sarà l'ideale in tutti i complessi scenari paralleli; applicare in modo efficace progetti paralleli complessi richiede una comprensione e un approccio molto diversi. questi semplici modelli sono spesso distaccati o hanno un'interazione banale con altri componenti del sistema. allo stesso modo, molte implementazioni di questi modelli banali non si adattano bene a sistemi paralleli complessi in modo efficace: un cattivo progetto parallelo complesso può impiegare il tempo necessario per eseguire il modello semplice. ill: esegue due volte più velocemente del modello a thread singolo, mentre utilizza 8 core logici durante l'esecuzione. gli esempi più comuni stanno usando / creando troppi thread e alti livelli di interferenza di sincronizzazione. in generale, questo è chiamato rallentamento parallelo. è abbastanza facile da incontrare se si affrontano tutti i problemi paralleli come semplici problemi.

quindi, diciamo che veramente dovrebbe utilizzare un multithreading efficiente nei tuoi programmi (la minoranza, nel clima di oggi): dovrai impiegare il modello semplice in modo efficace per apprendere il modello complesso e poi reimparare come ti avvicini al flusso del programma e all'interazione. il modello complesso è quello in cui dovrebbe essere in definitiva il tuo programma poiché è lì che si trova l'hardware oggi e dove verranno apportati i miglioramenti più importanti.

l'esecuzione di modelli semplici può essere immaginata come una forcella e i modelli complessi funzionano come un ecosistema complesso. Penso che la comprensione di modelli semplici, incluso il blocco generale e il threading, dovrebbe essere o sarà presto prevista dagli sviluppatori intermedi quando il dominio (in cui lo sviluppate) lo utilizza. la comprensione di modelli complessi è ancora un po 'insolita oggi (nella maggior parte dei domini), ma penso che la domanda aumenterà abbastanza rapidamente. come sviluppatori, molto più dei nostri programmi dovrebbero supportare questi modelli, e la maggior parte dell'uso è piuttosto indietro nella comprensione e nell'implementazione di questi concetti. Poiché i conteggi dei processori logici sono una delle aree più importanti del miglioramento dell'hardware, la richiesta di persone che comprendono e possono implementare sistemi complessi aumenterà sicuramente.

infine, ci sono molte persone che pensano che la soluzione sia solo "aggiungere la parallelizzazione". spesso è meglio rendere più veloce l'implementazione esistente. è molto più semplice e molto più semplice in molti casi. molti programmi in natura non sono mai stati ottimizzati; alcune persone hanno appena avuto l'impressione che la versione non ottimizzata sarebbe presto eclissata dall'hardware. migliorare la progettazione o le alghe di programmi esistenti è anche un'importante abilità se le prestazioni sono importanti - il ricorso a più core ai problemi non è necessariamente la soluzione migliore o più semplice.

quando si prendono di mira i PC moderni, la maggior parte di noi che ha bisogno di implementare buoni sistemi paralleli non dovrà andare oltre il multithreading, il locking, le librerie parallele, la lettura di un libro e un sacco di esperienza nella scrittura e test dei programmi (sostanzialmente, ristrutturazione di come ti avvicini ai programmi di scrittura).

    
risposta data 27.09.2011 - 10:05
fonte
2

Lo facciamo, ma scriviamo software di calcolo pesante in modo da beneficiare direttamente di più core.

A volte lo scheduler sposta molto i thread tra i core. Se ciò non è accettabile, puoi giocare con l'affinità principale.

    
risposta data 24.09.2010 - 13:48
fonte
0

Allo stato attuale, la frequenza del processore non aumenterà nel prossimo futuro. Siamo bloccati attorno al marchio a 3 GHz (senza overclock). Certamente, per molte applicazioni potrebbe non essere necessario andare oltre il multi-threading di base. Ovviamente se stai costruendo un'applicazione per l'interfaccia utente, qualsiasi elaborazione intensiva dovrebbe essere eseguita su un thread in background.

Se stai costruendo un'applicazione che sta elaborando enormi quantità di dati che devono essere in tempo reale, allora sì, probabilmente dovresti esaminare la programmazione multi-threading.

Per la programmazione multi-thread, scoprirai che otterrai rendimenti decrescenti sulla tua performance; puoi passare ore e migliorare il programma del 15%, quindi trascorrere un'altra settimana e migliorarlo solo di un ulteriore 5%.

    
risposta data 24.09.2010 - 16:51
fonte

Leggi altre domande sui tag