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 int
puntatore!). 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 restrict
parola 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 restrict
parola 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.