Os idiomas têm conjuntos de recursos semelhantes. A diferença de desempenho vem do fato de que Fortran diz que o aliasing não é permitido, a menos que uma instrução EQUIVALENCE seja usada. Qualquer código com alias não é Fortran válido, mas cabe ao programador e não ao compilador detectar esses erros. Assim, os compiladores Fortran ignoram possíveis aliases de ponteiros de memória e permitem gerar código mais eficiente. Veja este pequeno exemplo em 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;
}
}
Essa função seria mais lenta que a do Fortran após a otimização. Por quê então? Se você escrever valores na matriz de saída, poderá alterar os valores da matriz. Afinal, os ponteiros podem se sobrepor e apontar para o mesmo pedaço de memória (incluindo o int
ponteiro!). O compilador C é forçado a recarregar os quatro valores da matriz da memória para todos os cálculos.
No Fortran, o compilador pode carregar os valores da matriz uma vez e armazená-los nos registros. Isso pode ser feito porque o compilador Fortran assume que ponteiros / matrizes não se sobrepõem na memória.
Felizmente, a restrict
palavra-chave e o apelido estrito foram introduzidos no padrão C99 para solucionar esse problema. Também é bem suportado na maioria dos compiladores C ++ atualmente. A palavra-chave permite que você dê ao compilador uma dica de que o programador promete que um ponteiro não faz alias com nenhum outro ponteiro. O aliasing estrito significa que o programador promete que ponteiros de tipos diferentes nunca se sobrepõem, por exemplo, a double*
não se sobrepõe a um int*
(com a exceção específica de que char*
e void*
pode se sobrepor a qualquer coisa).
Se você usá-los, obterá a mesma velocidade do C e do Fortran. No entanto, a capacidade de usar a restrict
palavra - chave apenas com funções críticas de desempenho significa que os programas C (e C ++) são muito mais seguros e fáceis de escrever. Por exemplo, considere o código Fortran inválido:, CALL TRANSFORM(A(1, 30), A(2, 31), A(3, 32), 30)
que a maioria dos compiladores Fortran compila alegremente sem nenhum aviso, mas introduz um bug que só aparece em alguns compiladores, em algum hardware e com algumas opções de otimização.