Fortran è più facile da ottimizzare rispetto a C per i calcoli pesanti?


410

Di tanto in tanto leggo che Fortran è o può essere più veloce di C per calcoli pesanti. È davvero vero? Devo ammettere che non conosco quasi Fortran, ma il codice Fortran che ho visto finora non mostrava che il linguaggio avesse caratteristiche che C non aveva.

Se è vero, per favore dimmi perché. Per favore, non dirmi quali lingue o librerie sono buone per lo scricchiolio dei numeri, non ho intenzione di scrivere un'app o librerie per farlo, sono solo curioso.


53
Non molto soggettivo dalle risposte fornite di seguito. Il titolo corretto è "Esistono ragioni architettoniche fondamentali per cui un compilatore Fortran POTREBBE produrre un codice optomizzato migliore di un compilatore C", ma questo è solo un pignolo.
Martin Beckett,

3
La domanda sul titolo non è tanto soggettiva in quanto è un malinteso, penso. La domanda più dettagliata non è soggettiva.
jfm3,

1
Non penso che nessuno imparerebbe molto da questo oltre alla risposta "Sì" e "No" allo stesso tempo, e varia in base a compilatore, sorgente, CPU, layout di memoria, ecc. Ecc. Sbadiglio.
user7116,

1
Non penso che la domanda o le risposte siano soggettive. Ma se pensi che questa bandiera aiuti qualcuno, sto bene.
Quinmars,

2
@sixlettervariables sebbene tu e io conosciamo già la risposta, è una domanda che si presenta alla maggior parte delle persone all'inizio della loro carriera ed è importante capire la risposta. Invece di pubblicare un commento sprezzante, perché non trovare una risposta con cui sei d'accordo e dare +1
MarkJ

Risposte:


447

Le lingue hanno set di funzionalità simili. La differenza di prestazioni deriva dal fatto che Fortran afferma che l'aliasing non è consentito, a meno che non venga utilizzata un'istruzione EQUIVALENCE. Qualsiasi codice con alias non è valido Fortran, ma spetta al programmatore e non al compilatore rilevare questi errori. Pertanto i compilatori Fortran ignorano il possibile aliasing dei puntatori di memoria e consentono loro di generare codice più efficiente. Dai un'occhiata a questo piccolo esempio in C:

void transform (float *output, float const * input, float const * matrix, int *n)
{
    int i;
    for (i=0; i<*n; i++)
    {
        float x = input[i*2+0];
        float y = input[i*2+1];
        output[i*2+0] = matrix[0] * x + matrix[1] * y;
        output[i*2+1] = matrix[2] * x + matrix[3] * y;
    }
}

Questa funzione sarebbe più lenta della controparte Fortran dopo l'ottimizzazione. Perchè così? Se si scrivono valori nell'array di output, è possibile modificare i valori di matrice. Dopotutto, i puntatori potrebbero sovrapporsi e puntare allo stesso pezzo di memoria (incluso il intpuntatore!). Il compilatore C è costretto a ricaricare i quattro valori della matrice dalla memoria per tutti i calcoli.

In Fortran il compilatore può caricare una volta i valori della matrice e memorizzarli nei registri. Può farlo perché il compilatore Fortran presuppone che i puntatori / le matrici non si sovrappongano nella memoria.

Fortunatamente, la restrictparola chiave e il rigoroso alias sono stati introdotti nello standard C99 per risolvere questo problema. Al giorno d'oggi è ben supportato dalla maggior parte dei compilatori C ++. La parola chiave consente di dare al compilatore un suggerimento che il programmatore promette che un puntatore non si alias con nessun altro puntatore. I mezzi rigorosi-aliasing che le promesse programmatore che i puntatori di tipo diverso non sarà mai si sovrappongono, ad esempio, una double*volontà non sovrapposizione con una int*(con l'eccezione specifica che char*e void*possono sovrapporsi con qualsiasi cosa).

Se li usi otterrai la stessa velocità da C e Fortran. Tuttavia, la possibilità di utilizzare la restrictparola chiave solo con funzioni critiche per le prestazioni significa che i programmi C (e C ++) sono molto più sicuri e più facili da scrivere. Ad esempio, considera il codice Fortran non valido: CALL TRANSFORM(A(1, 30), A(2, 31), A(3, 32), 30)che la maggior parte dei compilatori Fortran compilerà felicemente senza alcun preavviso, ma introduce un bug che viene visualizzato solo su alcuni compilatori, su alcuni hardware e con alcune opzioni di ottimizzazione.


26
Tutto vero e valido, Jeff. Tuttavia, non considero sicuro l'interruttore "Assumere nessun aliasing". Può rompere il codice ereditato da altri progetti in modi così sottili che preferirei non usarlo. Sono diventato un nazista restrittivo per questo motivo :-)
Nils Pipenbrinck,

3
Per il mio secondo punto, non è necessario utilizzare l'opzione del compilatore no alias. Basta scrivere il codice in modo che i carichi basati sul puntatore siano prima assegnati in una variabile automatica e quindi lavorare con gli automatici da lì. Sembrerà più dettagliato, ma verrà ottimizzato perfettamente dal compilatore.
Tall Jeff,

33
Un buon esempio è la semplice esistenza di memcpy () vs. memmove (). A differenza di memcpy (), memmove () affronta aree sovrapposte, pertanto memcpy () può essere più veloce di memmove (). Questo problema era una ragione sufficiente per qualcuno per includere due funzioni anziché una nella libreria standard.
jfs,

12
Penso che sia stato questo il punto di Sebastian - a causa della complessità / flessibilità della gestione della memoria C, anche qualcosa di semplice come spostare la memoria è complicato.
Martin Beckett,

3
Il tuo call transformesempio non ha molto senso.
Vladimir F,

163

Sì, nel 1980; nel 2008? dipende

Quando ho iniziato a programmare professionalmente il dominio della velocità di Fortran era appena stato messo alla prova. Ricordo di averlo letto nel dottor Dobbs e di aver parlato dell'articolo ai programmatori più anziani: ridevano.

Quindi ho due opinioni su questo, teorico e pratico. In teoria, Fortran oggi non ha alcun vantaggio intrinseco in C / C ++ o in qualsiasi linguaggio che consenta il codice assembly. In pratica, Fortran oggi gode ancora dei vantaggi dell'eredità di una storia e cultura costruita attorno all'ottimizzazione del codice numerico.

Fino a Fortran 77 compreso, le considerazioni sulla progettazione del linguaggio avevano come obiettivo principale l'ottimizzazione. A causa dello stato della teoria e della tecnologia del compilatore, ciò spesso significava limitare le funzionalità e le capacità al fine di offrire al compilatore la possibilità migliore di ottimizzare il codice. Una buona analogia è pensare a Fortran 77 come una macchina da corsa professionale che sacrifica le caratteristiche per la velocità. In questi giorni i compilatori sono migliorati in tutte le lingue e le funzionalità per la produttività del programmatore sono più apprezzate. Tuttavia, ci sono ancora posti in cui le persone si preoccupano principalmente della velocità nell'informatica scientifica; queste persone hanno probabilmente ereditato codice, formazione e cultura da persone che erano loro stesse programmatori Fortran.

Quando si inizia a parlare dell'ottimizzazione del codice ci sono molti problemi e il modo migliore per farsi un'idea è nascondersi dove le persone hanno il compito di avere un codice numerico veloce . Ma tieni presente che un codice così critico in genere è una piccola parte delle linee complessive di codice e molto specializzato: un sacco di codice Fortran è altrettanto "inefficiente" come un sacco di altro codice in altre lingue e l' ottimizzazione non dovrebbe nemmeno essere una preoccupazione primaria di tale codice .

Un posto meraviglioso per iniziare a conoscere la storia e la cultura di Fortran è Wikipedia. La voce di Wikipedia su Fortran è superba e apprezzo moltissimo coloro che hanno impiegato il tempo e gli sforzi per renderla preziosa per la comunità di Fortran.

(Una versione abbreviata di questa risposta sarebbe stata un commento nell'eccellente thread iniziato da Nils ma non ho il karma per farlo. In realtà, probabilmente non avrei scritto nulla ma per questo questo thread ha effettivamente contenuto informativo e condivisione al contrario delle guerre di fiamma e del bigottismo linguistico, che è la mia esperienza principale su questo argomento. Ero sopraffatto e dovevo condividere l'amore.)


1
il link: web.archive.org/web/20090401205830/http://ubiety.uwaterloo.ca/… non funziona più. C'è un link alternativo?
nathanielng,

64

In una certa misura Fortran è stato progettato tenendo presente l'ottimizzazione del compilatore. Il linguaggio supporta operazioni di array interi in cui i compilatori possono sfruttare il parallelismo (specialmente su processori multi-core). Per esempio,

La moltiplicazione a matrice densa è semplicemente:

matmul(a,b)

La norma L2 di un vettore x è:

sqrt(sum(x**2))

Inoltre dichiarazioni come FORALL, PURE& ELEMENTALprocedure ecc. Aiutano ulteriormente a ottimizzare il codice. Persino i puntatori in Fortran non sono flessibili come C a causa di questo semplice motivo.

L'imminente standard Fortran (2008) ha co-array che consentono di scrivere facilmente codice parallelo. G95 (open source) e compilatori di CRAY lo supportano già.

Quindi sì, Fortran può essere veloce semplicemente perché i compilatori possono ottimizzarlo / parallelizzarlo meglio di C / C ++. Ma di nuovo come tutto il resto nella vita ci sono compilatori buoni e compilatori cattivi.



1
Il forallcostrutto è obsoleto perché i compilatori non sono stati in grado di ottimizzare bene il codice. La sostituzione è do concurrent. Inoltre, il codice sqrt(sum(x**2))sembra inefficiente, perché il compilatore probabilmente costruisce l'intero vettore x**2. Immagino che un ciclo sia migliore, ma è sicuramente meglio chiamare la norm2funzione intrinseca .
A. Hennink,

39

È divertente che molte risposte qui non conoscano le lingue. Ciò è particolarmente vero per i programmatori C / C ++ che hanno aperto e vecchio il codice FORTRAN 77 e discutono dei punti deboli.

Suppongo che il problema della velocità sia principalmente una questione tra C / C ++ e Fortran. In un codice enorme, dipende sempre dal programmatore. Ci sono alcune caratteristiche del linguaggio che Fortran supera e alcune caratteristiche che C fa. Quindi, nel 2011, nessuno può davvero dire quale è più veloce.

Per quanto riguarda la lingua stessa, Fortran al giorno d'oggi supporta le funzionalità Full OOP ed è completamente compatibile con le versioni precedenti. Ho usato a fondo il Fortran 2003 e direi che è stato delizioso usarlo. Per alcuni aspetti, Fortran 2003 è ancora dietro C ++ ma diamo un'occhiata all'utilizzo. Fortran viene utilizzato principalmente per il calcolo numerico e nessuno utilizza fantasiose funzionalità C ++ OOP per motivi di velocità. Nel calcolo ad alte prestazioni, C ++ non ha quasi nessun posto dove andare (dai un'occhiata allo standard MPI e vedrai che C ++ è stato deprecato!).

Al giorno d'oggi, puoi semplicemente programmare in linguaggio misto con Fortran e C / C ++. Ci sono persino interfacce per GTK + in Fortran. Ci sono compilatori gratuiti (gfortran, g95) e molti altri eccellenti commerciali.


8
Potresti aggiungere una fonte, un'esperienza specifica o un istituto scientifico / agenzia di elaborazione ad alte prestazioni che si sta allontanando dal C ++ per progetti futuri o riscrivendo i progetti c ++ in un'altra lingua. Lo chiedo solo perché conosco almeno due istituzioni scientifiche, Sandia e CERN, che usano pesantemente il c ++ per i loro modelli ad alte prestazioni. Inoltre, Sandia ha convertito uno dei loro software di modellazione (LAMMPS) da fortran a c ++ aggiungendo una serie di fantastici miglioramenti.
Zachary Kraus,

7
LAMMPS è scritto in C ++ estremamente semplice che non sfrutta la maggior parte delle funzionalità moderne del linguaggio. Rappresenta il C ++ che i programmatori Fortran che conoscono C scrivono dopo aver appreso C ++ 98. Questo non vuol dire che LAMMPS sia scritto male, solo che non è l'esempio che si desidera citare quando si fa appello al C ++ in HPC.
Jeff,

30

Ci sono diversi motivi per cui Fortran potrebbe essere più veloce. Tuttavia, la quantità che contano è così insignificante o può essere aggirata comunque, che non dovrebbe importare. Il motivo principale per utilizzare Fortran al giorno d'oggi è la manutenzione o l'estensione di applicazioni legacy.

  • Parole chiave PURE ed ELEMENTAL sulle funzioni. Queste sono funzioni che non hanno effetti collaterali. Ciò consente l'ottimizzazione in alcuni casi in cui il compilatore sa che la stessa funzione verrà chiamata con gli stessi valori. Nota: GCC implementa "puro" come estensione della lingua. Anche altri compilatori possono. Anche l'analisi tra moduli può eseguire questa ottimizzazione, ma è difficile.

  • insieme standard di funzioni che si occupano di array, non di singoli elementi. Roba come sin (), log (), sqrt () accetta array invece di scalari. Ciò semplifica l'ottimizzazione della routine. La vettorializzazione automatica offre gli stessi vantaggi nella maggior parte dei casi se queste funzioni sono incorporate o incorporate

  • Tipo complesso incorporato. In teoria, ciò potrebbe consentire al compilatore di riordinare o eliminare determinate istruzioni in alcuni casi, ma probabilmente vedresti lo stesso vantaggio con la struttura {double re, im; }; linguaggio usato in C. Rende per uno sviluppo più veloce anche se gli operatori lavorano su tipi complessi in fortran.


1
"ma probabilmente vedresti lo stesso beneficio con il { double re, im; };linguaggio usato in C". Molto probabilmente i compilatori C restituiranno quella struttura in forma sret con lo stack del chiamante che alloca spazio, passando un puntatore alla chiamata che lo riempie. Questo è molte volte più lento rispetto alla restituzione di più valori nei registri come farebbe un compilatore Fortran. Si noti che C99 ha risolto questo problema nel caso speciale di complesso.
Jon Harrop,

Non sono sicuro di essere d'accordo con il tuo motivo principale. Personalmente mi piace usare fortran per il codice pesante della matematica in cui gli array e le funzioni matematiche sono la parte più importante del codice. Ma so per certo che in molte istituzioni governative e banche continuano a usare fortran per mantenere o estendere il codice legacy. Personalmente ho usato fortran per estendere il codice a un professore nel mio dottorato di ricerca. comitato ha scritto.
Zachary Kraus,

La tua affermazione, "il motivo principale per usare Fortran al giorno d'oggi è mantenere o estendere le applicazioni legacy", è completamente sbagliata. Devo ancora vedere qualsiasi altro linguaggio di programmazione anche da remoto vicino alle funzionalità fornite da Fortran, specialmente per le applicazioni matematiche. Ne hai già nominati alcuni, come un superbo supporto di array, funzioni aritmetiche complesse integrate, pure o elementali - e potrei anche nominarne di più. Solo questo è sufficiente per dimostrare che la tua affermazione sopra è sbagliata.
Pap

28

Penso che il punto chiave a favore di Fortran sia che è un linguaggio leggermente più adatto per esprimere la matematica basata su vettori e array. Il problema di analisi del puntatore sopra indicato è in pratica reale, poiché il codice portatile non può davvero supporre che si possa dire qualcosa a un compilatore. Vi è SEMPRE un vantaggio nell'espressione computaitons in un modo più vicino a come appare il dominio. C non ha affatto array, se guardi da vicino, solo qualcosa che si comporta in questo modo. Fortran ha veri e propri arrawys. Ciò rende più semplice la compilazione per determinati tipi di algoritmi, in particolare per macchine parallele.

Nel profondo di cose come il sistema di runtime e le convenzioni di chiamata, C e il moderno Fortran sono sufficientemente simili che è difficile capire cosa farebbe la differenza. Si noti che C qui è davvero C: C ++ è un problema totalmente diverso con caratteristiche prestazionali molto diverse.


25

Non esiste una lingua più veloce di un'altra, quindi la risposta corretta è no .

Quello che devi veramente chiedere è "il codice compilato con il compilatore X Fortran è più veloce del codice equivalente compilato con il compilatore C Y?" La risposta a questa domanda ovviamente dipende da quali due compilatori scegli.

Un'altra domanda che ci si potrebbe porre sarebbe sulla falsariga di "Dato lo stesso sforzo profuso per ottimizzare i propri compilatori, quale compilatore produrrebbe un codice più veloce?" La risposta a questo sarebbe infatti Fortran . I compilatori Fortran hanno i vantaggi di Certian:

  • Fortran ha dovuto competere con Assembly nel giorno in cui alcuni giurarono di non usare mai compilatori, quindi è stato progettato per la velocità. C è stato progettato per essere flessibile.
  • La nicchia di Fortran è stata il numero schiacciante. In questo codice di dominio non è mai abbastanza veloce. Quindi c'è sempre stata molta pressione per mantenere efficiente la lingua.
  • La maggior parte della ricerca sulle ottimizzazioni del compilatore viene effettuata da persone interessate ad accelerare il codice di scricchiolio dei numeri di Fortran, quindi l'ottimizzazione del codice di Fortran è un problema molto più noto rispetto all'ottimizzazione di qualsiasi altro linguaggio compilato, e le nuove innovazioni compaiono prima nei compilatori di Fortran.
  • Biggie : C incoraggia un uso molto più puntatore di Fortran. Ciò aumenta drasticamente la portata potenziale di qualsiasi elemento di dati in un programma C, il che li rende molto più difficili da ottimizzare. Nota che Ada è anche molto meglio di C in questo regno, ed è un linguaggio OO molto più moderno rispetto al comune Fortran77. Se vuoi un linguaggio OO in grado di generare un codice più veloce di C, questa è un'opzione per te.
  • A causa della sua nicchia di numeri, i clienti dei compilatori Fortran tendono a preoccuparsi di più dell'ottimizzazione rispetto ai clienti dei compilatori C.

Tuttavia, non c'è nulla che impedisca a qualcuno di impegnarsi moltissimo nell'ottimizzazione del proprio compilatore C e di farlo generare un codice migliore rispetto al compilatore Fortran della propria piattaforma. In effetti, le maggiori vendite generate dai compilatori C rendono questo scenario abbastanza fattibile


4
Sono d'accordo. E posso aggiungere che quando fu introdotto Fortran (era la prima lingua di alto livello) alla fine degli anni '50, all'inizio degli anni '60, molti erano scettici su quanto potesse essere efficiente. Pertanto i suoi sviluppatori dovevano dimostrare che Fortran poteva essere efficiente e utile e si apprestava a "ottimizzarlo fino alla morte" solo per dimostrare il loro punto. C arrivò molto più tardi (dalla prima metà degli anni '70) e non aveva nulla da dimostrare, per così dire. Ma a questo punto era stato scritto un sacco di codice Fortran, quindi la comunità scientifica vi si è attenuto e lo fa ancora. Non programma Fortran ma ho imparato a collegarmi per chiamare le subroutine Fortran dal C ++.
Olumide,

3
La ricerca sull'ottimizzazione del compilatore è stata più diversificata di quanto sembri pensare. La storia delle implementazioni LISP, ad esempio, è piena di successi nel fare scricchiolii di numeri più velocemente di Fortran (che rimane il contendente predefinito da sfidare). Inoltre, gran parte dell'ottimizzazione del compilatore ha preso di mira le rappresentazioni intermedie del compilatore, il che significa che, a parte le differenze di semantica (come l'aliasing), si applicano a qualsiasi linguaggio di programmazione di una determinata classe.
Nessun uomo,

2
L'idea si ripete molto, ma è un po 'disonesto dire che non ci sono conseguenze per l'efficienza inerenti alla progettazione di un linguaggio di programmazione. Alcune funzionalità del linguaggio di programmazione comportano necessariamente inefficienze perché limitano le informazioni disponibili al momento della compilazione.
Prassolitico il

@Praxeolitic - È del tutto corretto (motivo per cui mi fa piacere non aver detto nulla del genere).
TED

@TED ​​Onestamente, tornando qui qualche mese dopo non ho idea del perché ho lasciato quel commento sulla tua risposta. Forse intendevo lasciarlo altrove? XP
Prassolitico

22

C'è un altro elemento in cui Fortran è diverso da C - e potenzialmente più veloce. Fortran ha regole di ottimizzazione migliori di C. In Fortran, l'ordine di valutazione di un'espressione non è definito, il che consente al compilatore di ottimizzarlo - se si vuole forzare un certo ordine, si devono usare le parentesi. In C l'ordine è molto più rigoroso, ma con le opzioni "-fast" sono più rilassate e anche "(...)" viene ignorato. Penso che Fortran abbia un modo che sta bene nel mezzo. (Bene, IEEE rende la vita più difficile poiché alcune modifiche dell'ordine di valutazione richiedono che non si verifichino overflow, che devono essere ignorati o ostacolano la valutazione).

Un'altra area di regole più intelligenti sono i numeri complessi. Non solo che ci sono voluti fino a quando C 99 li aveva, ma anche le regole che li governano sono migliori a Fortran; poiché la libreria Fortran di gfortran è parzialmente scritta in C ma implementa la semantica Fortran, GCC ha ottenuto l'opzione (che può essere utilizzata anche con programmi C "normali"):

-fcx-fortran-rules La moltiplicazione e la divisione complesse seguono le regole di Fortran. La riduzione dell'intervallo viene eseguita come parte di una divisione complessa, ma non è possibile verificare se il risultato di una moltiplicazione o divisione complessa sia "NaN + I * NaN", nel tentativo di salvare la situazione in quel caso.

Le regole di alias sopra menzionate sono un altro vantaggio e anche - almeno in linea di principio - le operazioni dell'intero array, che se prese correttamente in considerazione dall'ottimizzatore del compilatore, possono portare codice più veloce. D'altro canto, alcune operazioni richiedono più tempo, ad esempio se si esegue un'assegnazione a un array allocabile, ci sono molti controlli necessari (riallocare? [Funzionalità Fortran 2003], ha i passi da array, ecc.), Che rendono il operazione semplice più complessa dietro le quinte - e quindi più lenta, ma rende il linguaggio più potente. D'altra parte, le operazioni di array con limiti e passi flessibili facilitano la scrittura del codice e il compilatore di solito ottimizza il codice meglio di un utente.

In totale, penso che sia C che Fortran siano altrettanto veloci; la scelta dovrebbe essere più di quale linguaggio piace di più o se usare le operazioni dell'intero array di Fortran e la sua migliore portabilità siano più utili - o l'interfaccia migliore con le librerie dell'interfaccia utente grafica e di sistema in C.


Cosa c'è di significativo "salvataggio" nel caso Nan + INan? Ciò che rende gli infiniti diversi da NaN è che gli infiniti sono firmati. Le operazioni che coinvolgono infiniti non complessi che produrrebbe un segno confuso producono NaN e non vedo motivo per cui numeri complessi dovrebbero fare diversamente. Se si moltiplica (DBL_MAX, DBL_MAX) per (2,2), quadra il risultato e quindi quadra quel risultato, quale dovrebbe essere il segno del risultato in assenza di overflow? Che cosa invece si moltiplica per (1.001, DBL_MAX)? Considererei (NaN, NaN) la risposta corretta e ogni combinazione di infinito e NaN come priva di senso.
supercat

14

Non c'è nulla nelle lingue Fortran e C che rende l'una più veloce dell'altra per scopi specifici. Ci sono cose su compilatori specifici per ognuna di queste lingue che rendono alcuni favorevoli ad alcuni compiti più di altri.

Per molti anni, esistevano compilatori Fortran che potevano fare la magia nera alle tue routine numeriche, rendendo molti calcoli importanti follemente veloci. Anche i compilatori C contemporanei non potevano farlo. Di conseguenza, un certo numero di grandi librerie di codice è cresciuto in Fortran. Se vuoi usare queste librerie ben collaudate, mature e meravigliose, fai fuori il compilatore Fortran.

Le mie osservazioni informali mostrano che oggigiorno le persone codificano le loro pesanti cose computazionali in qualsiasi vecchia lingua, e se impiega un po 'di tempo trovano tempo su un cluster di calcolo economico. La legge di Moore ci prende in giro tutti.


11
Quasi revocato questo. Il problema è che Fortran non hanno alcuni vantaggi intrinseci. Tuttavia, sei abbastanza convinto che la cosa importante da guardare è il compier, non la lingua.
TED

14

Metto a confronto la velocità di Fortran, C e C ++ con il classico benchmark Levine-Callahan-Dongarra di Netlib. La versione in più lingue, con OpenMP, è http://sites.google.com/site/tprincesite/levine-callahan-dongarra-vectors La C è più brutta, poiché è iniziata con la traduzione automatica, oltre all'inserimento di restrizioni e pragmi per alcuni compilatori. C ++ è solo C con modelli STL ove applicabile. A mio avviso, l'STL è un miscuglio se migliora la manutenibilità.

Esiste solo un minimo esercizio di allineamento delle funzioni automatiche per vedere fino a che punto migliora l'ottimizzazione, poiché gli esempi si basano sulla pratica tradizionale di Fortran in cui si fa poco affidamento sull'in-lining.

Il compilatore C / C ++ che ha di gran lunga l'uso più diffuso manca di auto-vettorializzazione, su cui questi benchmark fanno molto affidamento.

Per quanto riguarda il post che è arrivato poco prima: ci sono un paio di esempi in cui le parentesi sono usate in Fortran per dettare l'ordine di valutazione più veloce o più accurato. I compilatori C noti non hanno opzioni per osservare le parentesi senza disabilitare le ottimizzazioni più importanti.


La brutta traduzione è necessaria per superare il problema di aliasing. Devi dare al compilatore variabili simulate per dire che le variabili byref implementate come puntatori possono essere ottimizzate per il registro.
David,

12

Sono un programmatore hobbista e sono "mediocre" in entrambe le lingue. Trovo più facile scrivere codice Fortran veloce rispetto al codice C (o C ++). Sia Fortran che C sono linguaggi "storici" (per oggi standard), sono molto usati e hanno un compilatore gratuito e commerciale ben supportato.

Non so se sia un fatto storico, ma Fortran ha la sensazione di essere costruito per essere parallelo / distribuito / vettorializzato / qualunque-molti-core-ized. E oggi è praticamente la "metrica standard" quando parliamo di velocità: "scala?"

Per il puro scricchiolio della CPU adoro Fortran. Per tutto ciò che riguarda IO, trovo più facile lavorare con C. (è comunque difficile in entrambi i casi).

Ora, ovviamente, per il codice parallelo di matematica intensiva probabilmente si desidera utilizzare la GPU. Sia C che Fortran hanno molte interfacce CUDA / OpenCL più o meno ben integrate (e ora OpenACC).

La mia risposta moderatamente obiettiva è: se conosci entrambe le lingue ugualmente bene / male allora penso che Fortran sia più veloce perché trovo più facile scrivere codice parallelo / distribuito in Fortran di C. (una volta capito che puoi scrivere "freeform" fortran e non solo un rigoroso codice F77)

Ecco una seconda risposta per coloro che vogliono votarmi perché non gradiscono la prima risposta: entrambe le lingue hanno le funzionalità richieste per scrivere codice ad alte prestazioni. Quindi dipende dall'algoritmo che stai implementando (intensivo della cpu? Io intensivo? Intensivo della memoria?), L'hardware (single cpu? Multi-core? Distribuisci supercomputer? GPGPU? FPGA?), La tua abilità e, in definitiva, il compilatore stesso. Sia C che Fortran hanno un compilatore fantastico. (Sono seriamente stupito da quanto siano avanzati i compilatori Fortran ma anche i compilatori C).

PS: Sono contento che tu abbia escluso specificamente le librerie perché ho molte cose brutte da dire sulle librerie GUI di Fortran. :)


11

Ho fatto un po 'di matematica approfondita con FORTRAN e C per un paio d'anni. Dalla mia esperienza posso dire che a volte FORTRAN è davvero migliore di C ma non per la sua velocità (si può fare in modo che C funzioni più velocemente di FORTRAN usando lo stile di codifica appropriato) ma piuttosto a causa di librerie molto ben ottimizzate come LAPACK, e grazie a grande parallelizzazione. Secondo me, FORTRAN è davvero scomodo con cui lavorare, e i suoi vantaggi non sono abbastanza buoni per annullare tale inconveniente, quindi ora sto usando C + GSL per fare calcoli.


10

Qualsiasi differenza di velocità tra Fortran e C sarà più una funzione delle ottimizzazioni del compilatore e della libreria matematica sottostante utilizzata dal compilatore specifico. Non c'è nulla di intrinseco in Fortran che lo renderebbe più veloce di C.

Ad ogni modo, un buon programmatore può scrivere Fortran in qualsiasi lingua.


@Scott Clawson: hai fatto -1 e non so perché. Ho fatto +1 per rimediare a questo. Tuttavia, qualcosa da prendere in considerazione è che Fortran è in circolazione da più tempo di molti dei nostri genitori. Molto tempo impiegato per ottimizzare l'output del compilatore: D
user7116,

Sono d'accordo. Avevo appena pubblicato una risposta molto simile in parallelo.
Tall Jeff,

Il problema con l'alias puntatore in C è stato sollevato da altri, ma ci sono diversi metodi che il programmatore può usare sui compilatori moderni per gestirlo, quindi sono ancora d'accordo.
Tall Jeff,

1
@Kluge: "Non c'è nulla di intrinseco in Fortran che lo renderebbe più veloce di C". Alias ​​puntatore, restituendo valori composti nei registri, costrutti numerici di livello superiore incorporati ...
Jon Harrop,

9

Non ho sentito che Fortan sia significativamente più veloce di C, ma potrebbe essere concepibile in alcuni casi sarebbe più veloce. E la chiave non sta nelle caratteristiche linguistiche presenti, ma in quelle (di solito) assenti.

Un esempio sono i puntatori C. I puntatori C sono usati praticamente ovunque, ma il problema con i puntatori è che il compilatore di solito non è in grado di dire se stanno puntando a parti diverse dello stesso array.

Ad esempio se hai scritto una routine strcpy simile a questa:

strcpy(char *d, const char* s)
{
  while(*d++ = *s++);
}

Il compilatore deve funzionare supponendo che d e s possano essere array sovrapposti. Quindi non può eseguire un'ottimizzazione che produrrebbe risultati diversi quando gli array si sovrappongono. Come prevedibile, ciò limita notevolmente il tipo di ottimizzazioni che è possibile eseguire.

[Dovrei notare che C99 ha una parola chiave "restring" che dice esplicitamente ai compilatori che i puntatori non si sovrappongono. Si noti inoltre che anche il Fortran ha puntatori, con semantica diversa da quelli di C, ma i puntatori non sono onnipresenti come in C.]

Ma tornando al problema C vs. Fortran, è ipotizzabile che un compilatore Fortran sia in grado di eseguire alcune ottimizzazioni che potrebbero non essere possibili per un programma C (scritto direttamente). Quindi non sarei troppo sorpreso dall'affermazione. Tuttavia, mi aspetto che la differenza di prestazioni non sia così grande. [~ 5-10%]


9

Veloce e semplice: entrambi sono ugualmente veloci, ma Fortran è più semplice. Ciò che è veramente più veloce alla fine dipende dall'algoritmo, ma non c'è comunque una differenza di velocità considerevole. Questo è ciò che ho imparato in un seminario Fortran presso il centro di calcolo ad alte prestazioni Stuttgard, Germania, nel 2015. Lavoro sia con Fortran che con C e condivido questa opinione.

Spiegazione:

C è stato progettato per scrivere sistemi operativi. Quindi ha più libertà del necessario per scrivere codice ad alte prestazioni. In generale questo non è un problema, ma se non si programma con attenzione, si può facilmente rallentare il codice.

Fortran è stato progettato per la programmazione scientifica. Per questo motivo, supporta la scrittura della sintassi del codice veloce, poiché questo è lo scopo principale di Fortran. Contrariamente all'opinione pubblica, Fortran non è un linguaggio di programmazione obsoleto. Il suo ultimo standard è il 2010 e i nuovi compilatori sono pubblicati su base regolare, poiché la maggior parte del codice ad alte prestazioni è scritto in Fortran. Fortran supporta inoltre le funzionalità moderne come direttive del compilatore (in pragmi C).

Esempio: vogliamo dare una grande struttura come argomento di input a una funzione (fortran: subroutine). All'interno della funzione l'argomento non viene modificato.

C supporta entrambi, chiama per riferimento e chiama per valore, che è una funzione utile. Nel nostro caso, il programmatore potrebbe accidentalmente utilizzare la chiamata in base al valore. Questo rallenta notevolmente le cose, poiché la struttura deve essere prima copiata nella memoria.

Fortran funziona solo con la chiamata per riferimento, il che obbliga il programmatore a copiare la struttura a mano, se desidera davvero una chiamata in base al valore. Nel nostro caso fortran sarà automaticamente veloce quanto la versione C con chiamata per riferimento.


Riesci a scrivere un'applicazione parallela nativa in C (che significa, senza chiamare alcuna libreria?). No. Puoi scrivere un'applicazione parallela nativa in Fortran? Sì, in diversi modi. Ergo, Fortran è "più veloce". Anche se, per essere onesti, nel 2010 quando hai scritto il tuo commento, il supporto per il parallelismo e le funzionalità di co-array di Fortran probabilmente non erano così diffusi come lo sono ora.
Mali Remorker,

@MaliRemorker Ha scritto questo nel 2016, non nel 2010.
Kowalski il

A mio avviso, l'overhead della creazione di processi paralleli non è il fattore più rilevante per un linguaggio di programmazione chiamato "veloce". Più rilevanti sono considerazioni pratiche, come una pace di codice non performante. Quindi non aiuta nulla se si risparmia tempo una volta (quando si crea il processo parallelo) e lo si perde su più core in seguito. Il termine "veloce" dovrebbe anche considerare codici non paralleli. Per questo motivo, non riesco a vedere un argomento contro il mio punto. Forse il tuo commento è stato come risposta indipendente?
Markus Dutschke,

8

Generalmente FORTRAN è più lento di C. C può usare puntatori di livello hardware che consentono al programmatore di ottimizzare a mano. FORTRAN (nella maggior parte dei casi) non ha accesso agli hack di memoria dell'hardware. (VAX FORTRAN è un'altra storia.) Ho usato FORTRAN dentro e fuori dagli anni '70. (Veramente.)

Tuttavia, a partire dagli anni '90, FORTRAN si è evoluto per includere costrutti linguistici specifici che possono essere ottimizzati in algoritmi intrinsecamente paralleli che possono davvero urlare su un processore multi-core. Ad esempio, la vettorializzazione automatica consente a più processori di gestire contemporaneamente ogni elemento in un vettore di dati. 16 processori - 16 elementi vettoriali - l'elaborazione richiede 1/16 del tempo.

In C, devi gestire i tuoi thread e progettare con cura l'algoritmo per l'elaborazione multipla, quindi utilizzare una serie di chiamate API per assicurarti che il parallelismo avvenga correttamente.

In FORTRAN, devi solo progettare con cura il tuo algoritmo per l'elaborazione multipla. Il compilatore e il runtime possono gestire il resto per te.

Puoi leggere un po 'di High Performance Fortran , ma trovi molti link morti. Stai meglio leggendo sulla programmazione parallela (come OpenMP.org ) e su come FORTRAN lo supporti.


6
@ S.Lott: Non riuscivo a immaginare quanto terribile il codice C avrebbe dovuto sembrare buono come il semplice scritto Fortran per la maggior parte dei codici che abbiamo qui ... e io sono un programmatore C. Otterrai migliori prestazioni dal codice più semplice in Fortran. Non che tu o io non siamo riusciti a trovare un controesempio. : D
user7116,

2
@Greg Rogers: dovrai affrontare il problema con le persone di Vectortration di Fortran, non con me. Sto solo riferendo quello che ho letto. polyhedron.com/absoftlinux
S.Lott

2
-1 // "Generalmente FORTRAN è più lento di C. Questo è vero per quasi tutto." perché? // un argomento basato sulla facilità di utilizzo del multi-threading in Fortran vs C non sta dicendo qualcosa sulla performance.
steabert

4
@ S.Lott: "il multi-threading esiste solo per le prestazioni". Err no.
Jon Harrop,

4
@ S.Lott: "L'uso di C dei puntatori quasi a livello hardware consente a C di essere più veloce di Fortran". Err, no
Jon Harrop il

5

Il codice più veloce non è realmente all'altezza della lingua, è il compilatore in modo da poter vedere il "compilatore" ms-vb che genera un codice oggetto gonfio, più lento e ridondante che è legato insieme all'interno di un ".exe", ma powerBasic genera troppo codice migliore. Il codice oggetto creato dai compilatori C e C ++ viene generato in alcune fasi (almeno 2) ma, per progettazione, la maggior parte dei compilatori Fortran ha almeno 5 fasi, tra cui ottimizzazioni di alto livello, quindi, per progettazione, Fortran sarà sempre in grado di generare codice altamente ottimizzato. Quindi alla fine il compilatore non è la lingua che dovresti chiedere, il miglior compilatore che conosco è il compilatore Intel Fortran perché puoi ottenerlo su LINUX e Windows e puoi usare VS come IDE, se stai cercando un compilatore economico che puoi sempre inoltrare su OpenWatcom.

Maggiori informazioni su questo: http://ed-thelen.org/1401Project/1401-IBM-Systems-Journal-FORTRAN.html


3

Fortran ha routine di I / O migliori, ad es. La funzione do implicita offre flessibilità che la libreria standard di C non può eguagliare.

Il compilatore Fortran gestisce direttamente la sintassi più complessa coinvolta e poiché tale sintassi non può essere facilmente ridotta alla forma di passaggio degli argomenti, C non può implementarla in modo efficiente.


1
Hai dei benchmark che mostrano che Fortran batte C per I / O?
Jeff,

3

Utilizzando standard moderni e compilatore, no!

Alcune delle persone qui hanno suggerito che FORTRAN è più veloce perché il compilatore non deve preoccuparsi dell'aliasing (e quindi può fare più ipotesi durante l'ottimizzazione). Tuttavia, questo è stato affrontato in C dallo standard C99 (credo) con l'inclusione della parola chiave restringente. Il che sostanzialmente dice al compilatore, che all'interno di un ambito scope, il puntatore non è alias. Inoltre, C consente una corretta aritmetica dei puntatori, dove cose come l'aliasing possono essere molto utili in termini di prestazioni e allocazione delle risorse. Anche se penso che la versione più recente di FORTRAN consenta l'uso di puntatori "corretti".

Per le implementazioni moderne C in generale supera FORTRAN (sebbene sia anche molto veloce).

http://benchmarksgame.alioth.debian.org/u64q/fortran.html

MODIFICARE:

Una giusta critica a questo sembra essere che il benchmarking possa essere parziale. Ecco un'altra fonte (relativa a C) che mette il risultato in più contesto:

http://julialang.org/benchmarks/

Puoi vedere che C in genere supera Fortran nella maggior parte dei casi (vedi di nuovo le critiche che seguono che si applicano anche qui); come altri hanno affermato, il benchmarking è una scienza inesatta che può essere facilmente caricata per favorire una lingua rispetto ad altre. Ma mette in contesto come Fortran e C abbiano prestazioni simili.


4
Uno sarebbe uno sciocco a credere a qualcosa su Fortran da un post che presume che sia ancora FORTRAN. Ciò è cambiato più di 25 anni fa. Questi test non possono confrontare le lingue, perché usano compilatori di diversi fornitori sebbene sia Intel che GCC abbiano compilatori sia per C che per Fortran. Pertanto tali confronti sono privi di valore.
Vladimir F,

2

Fortran può gestire array, in particolare array multidimensionali, in modo molto conveniente. Affettare elementi di array multidimensionali in Fortran può essere molto più semplice di quello in C / C ++. Ora C ++ ha librerie in grado di fare il lavoro, come Boost o Eigen, ma lo sono dopo tutte le librerie esterne. In Fortran queste funzioni sono intrinseche.

Il fatto che Fortran sia più veloce o più conveniente per lo sviluppo dipende principalmente dal lavoro che devi completare. Come persona di calcolo scientifico per la geofisica, ho fatto la maggior parte del calcolo in Fortran (intendo il moderno Fortran,> = F90).


1
E anche se Fortran è più veloce dipende anche da: il compilatore che usi (è importante!), Per i lavori di calcolo se applichi un'adeguata parallelizzazione al codice e come viene scritto il codice.
Kai,

1

Questo è più che un po 'soggettivo, perché entra nella qualità dei compilatori e più di ogni altra cosa. Tuttavia, per rispondere più direttamente alla tua domanda, parlando dal punto di vista della lingua / del compilatore, non c'è nulla su Fortran su C che lo renderà intrinsecamente più veloce o migliore di C. Se stai facendo pesanti operazioni matematiche, scenderà al la qualità del compilatore, l'abilità del programmatore in ogni lingua e le intrinseche librerie di supporto matematico che supportano tali operazioni per determinare in definitiva quale sarà più veloce per una data implementazione.

EDIT: Altre persone come @Nils hanno sollevato il punto positivo sulla differenza nell'uso dei puntatori in C e sulla possibilità di aliasing che forse rallenta le implementazioni più ingenue in C. Tuttavia, ci sono modi per affrontarlo in C99 , tramite flag di ottimizzazione del compilatore e / o nel modo in cui la C è effettivamente scritta. Questo è ben coperto nella risposta di @Nils e nei successivi commenti che seguono sulla sua risposta.


Sembra un test di riferimento di un algoritmo. Che richiede meno tempo, FORTRAN o C? Non mi sembra soggettivo. Forse mi manca qualcosa.
S.Lott

1
Disaccordo. Stai confrontando i compilatori, non le lingue. Penso che la domanda originale sia se c'è qualcosa nella LINGUA che lo rende intrinsecamente migliore. Altre risposte qui stanno entrando in alcune sottili differenze discutibili, ma penso che siamo più d'accordo sul fatto che siano nel rumore.
Tall Jeff,

Questa non è l'analisi O (n) degli algoritmi. Sono le prestazioni. Non vedere come le prestazioni possano essere un ipotetico concetto indipendente dall'implementazione. Immagino che mi manchi qualcosa.
S.Lott

1
-1: "Non c'è nulla in Fortran su C che lo renderà intrinsecamente più veloce o migliore di C". Err no.
Jon Harrop,

0

La maggior parte dei post presenta già argomenti convincenti, quindi aggiungerò i proverbiali 2 centesimi a un aspetto diverso.

Essere alla fine più veloce o più lento in termini di potenza di elaborazione alla fine può avere la sua importanza, ma se ci vuole 5 volte più tempo per sviluppare qualcosa in Fortran perché:

  • manca una buona libreria per compiti diversi dal puro scricchiolio dei numeri
  • manca uno strumento decente per la documentazione e il test unitario
  • è un linguaggio con espressività molto bassa, che sale alle stelle il numero di righe di codice.
  • ha una pessima gestione delle stringhe
  • ha una quantità insana di problemi tra diversi compilatori e architetture che ti fanno impazzire.
  • ha una strategia I / O molto scarsa (LEGGI / SCRIVI di file sequenziali. Sì, esistono file ad accesso casuale ma li hai mai visti usati?)
  • non incoraggia le buone pratiche di sviluppo, la modularizzazione.
  • mancanza effettiva di un compilatore open source completamente standard e pienamente conforme (sia gfortran che g95 non supportano tutto)
  • interoperabilità molto scarsa con C (mangling: un carattere di sottolineatura, due caratteri di sottolineatura, nessun carattere di sottolineatura, in genere un carattere di sottolineatura ma due se c'è un altro carattere di sottolineatura.

Quindi il problema è irrilevante. Se qualcosa è lento, il più delle volte non è possibile migliorarlo oltre un determinato limite. Se vuoi qualcosa di più veloce, modifica l'algoritmo. Alla fine, il tempo del computer è economico. Il tempo umano non lo è. Valorizza la scelta che riduce il tempo umano. Se aumenta il tempo del computer, è comunque conveniente.


3
declassato perché anche se sollevi punti interessanti che si aggiungono a una discussione sui vantaggi / svantaggi di fortrans rispetto ad altre lingue (con cui non sono completamente d'accordo), questa non è davvero una risposta alla domanda ...
steabert

@steabert: in effetti, ho dettoI will just add the proverbial 2 cents to a different aspect
Stefano Borini il

1
+1 da parte mia per una risposta non pignola. Come hai detto, Fortran potrebbe essere più veloce in alcuni compiti rari (non ne ho visto nessuno personalmente). Ma la quantità di tempo che sprechi per mantenere un linguaggio non mantenibile rovina ogni possibile vantaggio.
André Bergner,

10
-1. Sembra che tu stia pensando a Fortran in termini di F77. Ciò è stato sostituito da F90, F95, F03 e F08.
Kyle Kanos,

4
Sottovalutato perché parla esclusivamente di un lato di un compromesso. La velocità di sviluppo può essere importante per la maggior parte della programmazione generale, ma ciò non lo rende l'unico compromesso valido. I programmatori di Fortran sono spesso scienziati / ingegneri che apprezzano la semplicità del linguaggio (FORmula TRANslation è estremamente facile da imparare e padroneggiare. C / C ++ non lo è ), le eccellenti librerie (spesso utilizzate da altre lingue) e la velocità (ad es. Simulazioni meteorologiche che richiedono giorni in Fortran, ma mesi se scritti interamente in altre lingue).
BraveNewCurrency

-3

Fortran tradizionalmente non imposta opzioni come -fp: strict (che ifort richiede per abilitare alcune delle funzionalità in USE IEEE_arithmetic, una parte dello standard f2003). Anche Intel C ++ non imposta -fp: rigoroso come predefinito, ma questo è necessario per la gestione di ERRNO, ad esempio, e altri compilatori C ++ non rendono conveniente disattivare ERRNO o ottenere ottimizzazioni come la riduzione del simd. gcc e g ++ mi hanno richiesto di impostare Makefile per evitare di usare la pericolosa combinazione -O3 -ffast-math -fopenmp -march = native. Oltre a questi problemi, questa domanda sulle prestazioni relative diventa più schizzinosa e dipende dalle regole locali sulla scelta dei compilatori e delle opzioni.


I recenti aggiornamenti di gcc hanno corretto il problema con la combinazione di Openmp e matematica veloce.
tim18

Questa risposta riguarda davvero gli utenti che non comprendono i flag predefiniti per i loro compilatori, non le lingue stesse.
Jeff,
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.