C'è qualcosa che impedisce l'implementazione di un compilatore C # multithread?

4

La famiglia di linguaggio C / C ++ apparentemente ha implementazioni di compilazione multithread che funzionano su parallelismo a livello di file, ma il compilatore Microsoft C # (csc.exe) è solo a thread singolo. MSBuild supporta l'edificio multithreaded, ma solo a livello di progetto, e ovviamente i progetti di dipendenza devono essere compilati prima dei progetti che dipendono da essi, quindi esistono limiti pratici al parallelismo.

Esiste un compilatore C # con multithreading di cui non sono a conoscenza? In caso contrario, c'è qualcosa riguardo alle specifiche del linguaggio C # che impedisce un compilatore C # multithread, o è solo "difficile" e quindi non ne vale la pena?

    
posta Scott Whitlock 02.09.2016 - 17:40
fonte

5 risposte

7

La risposta corretta è quasi certamente "perché lo stato corrente di multi-threading è già adeguato per l'attività." Oppure, se preferisci, "perché i costi di fornitura di multithreading aggiuntivo superano i benefici."

Come già sapete, l'implementazione di più thread in un programma non garantisce un miglioramento della velocità. I thread hanno un overhead, quindi a meno che il miglioramento delle prestazioni sia maggiore del sovraccarico, non ne vale la pena. L'utilizzo di troppi thread può effettivamente rallentare un programma. Se il programma è legato all'I / O, il numero ottimale di thread in esecuzione simultanea è probabilmente il numero di core del processore (8 nel mio computer, se si considera l'hyper-threading come core separati), ma è comunque necessario un modo per rompere il lavorare prima su singole unità.

Poiché il compilatore di Roslyn è scritto in C #, può approfitta della libreria parallela attività per parallelizzare alcune attività :

Both the native compilers and the Roslyn compilers are primarily single-threaded, but the higher-level pieces of Roslyn, such as the language services, take advantage of the Task Parallel Library (TPL) for multi-threading when calling the compiler APIs. For example, Visual Basic and C# methods are essentially standalone once parsed and can be compiled in parallel under Roslyn.

    
risposta data 02.09.2016 - 17:50
fonte
3

Non è parallelizzato perché non può essere parallelizzato. Il C ++ può essere parallelizzato perché l'interfaccia tra i file è codificata dal programmatore, quindi ogni file è perfettamente isolato da tutti gli altri.

Ma in C # non esiste una separazione così netta tra i file. Molto spesso, i file hanno una rete di riferimenti, che sono raramente chiari. Anche se fosse possibile parallelizzare qualcosa, sarebbe ben lontano dal vantaggio che il C ++ guadagni dal parallelismo.

Ma C # non ha davvero bisogno di parallelizzazione. C ++ ha bisogno di parallelizzazione perché ogni file è ENORME dopo che accade, quindi compilare un singolo file può richiedere molto più tempo rispetto alla compilazione di un file C # di complessità simile.

Ma i progetti C # sono parallelizzati a livello di soluzione. Se hai due progetti che non si riferiscono tra loro, possono essere costruiti in parallelo. Quindi se hai una soluzione con molti progetti e mantieni l'albero delle dipendenze relativamente piatto, esso compilerà molti progetti in parallelo.

    
risposta data 02.09.2016 - 18:32
fonte
2

Is there a multithreaded C# compiler that I'm not aware of? If not, is there something about the C# language specification that prevents a multithreaded C# compiler, or is it just "hard" and therefore not worth it?

No, no, stai pensando a questo nel modo sbagliato. Il compilatore C ++ fa in parallelo un lavoro mille volte maggiore di quello che fa il compilatore C # in serie. Non è necessario offrire la compilazione parallela di C # perché la compilazione C # non è eccessivamente costosa e con inutili confini tra file. Inoltre, do compila gli assembly in parallelo, che è molto più semplice e più equivalente a ciò che fa il compilatore C ++.

Fondamentalmente, il C ++ offre una compilazione parallela perché la compilazione C ++ è totalmente infranta. La compilazione C # non è interrotta.

    
risposta data 02.09.2016 - 20:06
fonte
2

Si potrebbe immaginare un compilatore parallelo. Ad esempio, si potrebbe immaginare un compilatore che compilerebbe parecchie funzioni (nello stesso file sorgente) in parallelo.

Ricorda che un compilatore non è per lo più un parser. In pratica, un compilatore che ottimizza la forza industriale sta spendendo la maggior parte del suo tempo trasformando alcune rappresentazioni interne del codice sorgente compilato perché le ottimizzazioni vengono eseguite trasformando le rappresentazioni interne. Quindi ogni funzione che si verifica nel codice sorgente potrebbe in teoria essere compilata in qualche modo separatamente (per compiti semplici come il piegamento costante, l'eliminazione di sottoespressione comune, ecc.) E solo in un secondo momento si unirebbero le loro rappresentazioni.

Il motivo per cui nessuno sta codificando un compilatore multi-threaded parallelo è che non esiste una teoria sostanziale che supporti tale progetto, quindi è necessario avviare da zero l'intera progettazione e implementazione del compilatore. È possibile, ma è davvero troppo costoso.

Ricorda che i compilatori di forza industriale sono grandi software , in genere diversi milioni di righe di codice sorgente. È difficile permettersi di riscriverli tutti, dato che la progettazione di un simile compilatore parallelo non è nota e non è possibile prevedere quanto si otterrebbe.

The C/C++ language family apparently has multithreaded compiler implementations

(Credo che tu abbia torto, o confondendo il programma builder -eg make su Linux- con il compilatore proprio -eg cc1plus avviato dal comando g++ -oftato da make . ..- su Linux con GCC )

A proposito, non ho mai sentito parlare di un compilatore C ++ o C multithread. Tutti quelli che conosco (in particolare Clang & GCC) sono programmi puramente sequenziali, mono-thread (e sono animali molto grandi, GCC ha più di decine di milioni di righe di codice sorgente). Ciò che è in qualche modo in grado di funzionare in parallelo - in diversi processi, non in thread - sono alcuni passaggi dell'intero programma di ottimizzazione (spesso chiamato ottimizzazione link-time cioè LTO che è g++ -flto -O2 per GCC, ma che LTO è ancora fatto dal compilatore). Ma il tuo costruttore (es. GNU make avviato come make -j ) sarebbe in grado di eseguire diversi processi di compilazione (lavorando su diversi unità di traduzione) in parallelo. Inoltre, il GNU gold linker è multi-threaded. E l'ottimizzazione link-time è usata raramente (e non sempre vale il costo, ad esempio g++ -O2 -flto spesso guadagnerebbe solo meno del 5% delle prestazioni wrt g++ -O2 ) perché rallenta significativamente il tempo di compilazione (es. Lo raddoppia).

    
risposta data 02.09.2016 - 18:58
fonte
1

Non c'è nulla nel linguaggio C che precluda un'implementazione del compilatore multi-thread.

Tuttavia, non è solo necessario.

I programmi Real-World sono costituiti da più componenti indipendenti. È possibile compilare questi componenti indipendenti in modo indipendente, con istanze del compilatore indipendenti. Di solito, ci sono più componenti individuali di quanti siano i core della CPU.

In effetti, esistono strumenti come distcc o IncrediBuild il cui scopo è di distribuire questi lavori di compilazione indipendenti attraverso un intero cluster di macchine. Ora, se abbiamo già bisogno di costruire cluster per essere in grado di far fronte al parallelismo già esistente a livello di processo nei compilatori (o piuttosto nei sistemi di compilazione), a cosa serve un ancor più parallelismo a livello di thread?

    
risposta data 08.09.2016 - 20:18
fonte

Leggi altre domande sui tag