¿Fortran es más fácil de optimizar que C para cálculos pesados?


410

De vez en cuando leo que Fortran es o puede ser más rápido que C para cálculos pesados. ¿Es eso realmente cierto? Debo admitir que apenas conozco a Fortran, pero el código de Fortran que he visto hasta ahora no muestra que el lenguaje tenga características que C no tiene.

Si es cierto, por favor dime por qué. Por favor, no me diga qué idiomas o libs son buenos para el cálculo de números, no tengo la intención de escribir una aplicación o lib para hacer eso, solo tengo curiosidad.


53
Realmente subjetivo de las respuestas dadas a continuación El título correcto es "¿Hay alguna razón arquitectónica fundamental por la que un compilador Fortran PODRÍA producir un mejor código optimizado que un compilador C", pero eso es solo una trampa.
Martin Beckett

3
La pregunta del título no es tan subjetiva como es un malentendido, creo. La pregunta más detallada no es subjetiva.
jfm3

1
No creo que nadie aprenda mucho de esto además de que la respuesta es "Sí" y "No" al mismo tiempo, y varía según el compilador, la fuente, la CPU, el diseño de la memoria, etc., etc. Bostezo.
user7116

1
No creo que la pregunta o las respuestas sean subjetivas. Pero si crees que esta bandera ayuda a alguien, estoy de acuerdo.
quinmars

2
@sixlettervariables aunque usted y yo ya sabemos la respuesta, es una pregunta que se le ocurre a la mayoría de las personas al inicio de sus carreras y es importante entender la respuesta. En lugar de realizar un comentario despectivo por qué no encontrar una respuesta que de acuerdo y dar 1
MarkJ

Respuestas:


447

Los idiomas tienen conjuntos de características similares. La diferencia de rendimiento proviene del hecho de que Fortran dice que el alias no está permitido, a menos que se use una declaración EQUIVALENCE. Cualquier código que tenga alias no es válido para Fortran, pero depende del programador y no del compilador detectar estos errores. Por lo tanto, los compiladores de Fortran ignoran el posible alias de los punteros de memoria y les permiten generar código más eficiente. Eche un vistazo a este pequeño ejemplo en 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;
    }
}

Esta función sería más lenta que la contraparte de Fortran después de la optimización. ¿Porque? Si escribe valores en la matriz de salida, puede cambiar los valores de la matriz. Después de todo, los punteros pueden superponerse y apuntar a la misma porción de memoria (¡incluido el intpuntero!). El compilador de C se ve obligado a recargar los cuatro valores de la matriz desde la memoria para todos los cálculos.

En Fortran, el compilador puede cargar los valores de la matriz una vez y almacenarlos en registros. Puede hacerlo porque el compilador Fortran supone que los punteros / matrices no se superponen en la memoria.

Afortunadamente, la restrictpalabra clave y el alias estricto se han introducido en el estándar C99 para abordar este problema. También es compatible con la mayoría de los compiladores de C ++ en estos días. La palabra clave le permite dar al compilador una pista de que el programador promete que un puntero no se alias con ningún otro puntero. El medio-aliasing estrictas que las promesas programador que los punteros de diferente tipo nunca se superponen, por ejemplo, una double*voluntad no se superponen con una int*(con la excepción específica que char*y void*puede solaparse con cualquier cosa).

Si los usas obtendrás la misma velocidad de C y Fortran. Sin embargo, la capacidad de usar la restrictpalabra clave solo con funciones críticas de rendimiento significa que los programas C (y C ++) son mucho más seguros y fáciles de escribir. Por ejemplo, considere el código no válido de Fortran: CALL TRANSFORM(A(1, 30), A(2, 31), A(3, 32), 30)que la mayoría de los compiladores de Fortran compilarán sin previo aviso, pero presenta un error que solo aparece en algunos compiladores, en algunos equipos y con algunas opciones de optimización.


26
Todo verdadero y válido, Jeff. Sin embargo, no considero seguro el interruptor "asumir sin alias". Puede romper el código heredado de otros proyectos de maneras tan sutiles que prefiero no usarlo. Me he convertido en un nazi restringido por esa razón :-)
Nils Pipenbrinck

3
Para mi segundo punto, no tiene que usar el modificador de compilación sin alias. Simplemente escriba el código para que las cargas basadas en puntero se asignen primero a una variable automática y luego trabaje con las automáticas desde allí. Se verá más detallado, pero el compilador lo optimizará perfectamente.
Alto Jeff

33
Un buen ejemplo es la mera existencia de memcpy () vs. memmove (). A diferencia de memcpy (), memmove () hace frente a áreas superpuestas, por lo tanto, memcpy () puede ser más rápido que memmove (). Este problema fue razón suficiente para que alguien incluyera dos funciones en lugar de una en la biblioteca estándar.
jfs

12
Creo que ese era el punto de Sebastian: debido a la complejidad / flexibilidad del manejo de la memoria C, incluso algo tan simple como mover la memoria es complicado.
Martin Beckett

3
Tu call transformejemplo no tiene mucho sentido.
Vladimir F

163

Si, en 1980; ¿en 2008? depende

Cuando comencé a programar profesionalmente, el dominio de la velocidad de Fortran estaba siendo desafiado. Recuerdo haber leído sobre esto en el Dr. Dobbs y contarles a los programadores mayores sobre el artículo, se rieron.

Así que tengo dos puntos de vista sobre esto, teórico y práctico. En teoría, Fortran hoy no tiene ninguna ventaja intrínseca para C / C ++ o incluso cualquier lenguaje que permita el código de ensamblaje. En la práctica, Fortran todavía disfruta de los beneficios del legado de una historia y una cultura basadas en la optimización del código numérico.

Hasta Fortran 77 inclusive, las consideraciones de diseño del lenguaje tenían la optimización como foco principal. Debido al estado de la teoría y la tecnología del compilador, esto a menudo significaba restringir las características y la capacidad para darle al compilador la mejor oportunidad de optimizar el código. Una buena analogía es pensar en Fortran 77 como un auto de carrera profesional que sacrifica características por la velocidad. En la actualidad, los compiladores han mejorado en todos los idiomas y las funciones para la productividad del programador son más valoradas. Sin embargo, todavía hay lugares donde las personas se preocupan principalmente por la velocidad en la informática científica; Es muy probable que estas personas hayan heredado el código, la capacitación y la cultura de personas que fueron programadores de Fortran.

Cuando uno comienza a hablar sobre la optimización del código, hay muchos problemas y la mejor manera de hacerse una idea es acechar dónde están las personas cuyo trabajo es tener un código numérico rápido . Pero tenga en cuenta que un código tan crítico suele ser una pequeña fracción de las líneas generales de código y muy especializado: una gran cantidad de código Fortran es tan "ineficiente" como muchos otros códigos en otros idiomas y la optimización ni siquiera debería ser Una preocupación principal de dicho código .

Un lugar maravilloso para comenzar a aprender sobre la historia y la cultura de Fortran es wikipedia. La entrada de Fortran Wikipedia es excelente y aprecio mucho a aquellos que se han tomado el tiempo y el esfuerzo para hacerla valiosa para la comunidad de Fortran.

(Una versión abreviada de esta respuesta habría sido un comentario en el excelente hilo iniciado por Nils, pero no tengo el karma para hacerlo. En realidad, probablemente no habría escrito nada en absoluto, pero para eso este hilo tiene real contenido de información y compartir en comparación con las guerras de llamas y la intolerancia lingüística, que es mi experiencia principal con este tema. Estaba abrumado y tuve que compartir el amor).


1
el enlace: web.archive.org/web/20090401205830/http://ubiety.uwaterloo.ca/… ya no funciona. ¿Hay un enlace alternativo?
nathanielng

64

Hasta cierto punto, Fortran ha sido diseñado teniendo en cuenta la optimización del compilador. El lenguaje admite operaciones de matriz completa donde los compiladores pueden explotar el paralelismo (especialmente en procesadores multi-core). Por ejemplo,

La multiplicación de matriz densa es simplemente:

matmul(a,b)

La norma L2 de un vector x es:

sqrt(sum(x**2))

Por otra parte, como declaraciones FORALL, PUREy ELEMENTALprocedimientos, etc. ayuda adicional al código optimizar. Incluso los punteros en Fortran no son tan flexibles como C debido a esta simple razón.

El próximo estándar Fortran (2008) tiene matrices conjuntas que le permiten escribir fácilmente código paralelo. G95 (código abierto) y los compiladores de CRAY ya lo admiten.

Entonces sí, Fortran puede ser rápido simplemente porque los compiladores pueden optimizarlo / paralelizarlo mejor que C / C ++. Pero nuevamente, como todo lo demás en la vida, hay buenos compiladores y malos compiladores.



1
La forallconstrucción está en desuso porque los compiladores no pudieron optimizar bien el código. El reemplazo es do concurrent. Además, el código sqrt(sum(x**2))parece ineficiente, porque el compilador probablemente construye todo el vector x**2. Supongo que un bucle es mejor, pero sin duda es mejor llamar a la norm2función intrínseca .
A. Hennink

39

Es curioso que muchas respuestas aquí por no saber los idiomas. Esto es especialmente cierto para los programadores de C / C ++ que han abierto y antiguo código FORTRAN 77 y discuten las debilidades.

Supongo que el problema de la velocidad es principalmente una cuestión entre C / C ++ y Fortran. En un código enorme, siempre depende del programador. Hay algunas características del lenguaje que Fortran supera y algunas características que hace C. Entonces, en 2011, nadie puede decir cuál es más rápido.

Sobre el lenguaje en sí, Fortran hoy en día es compatible con las funciones Full OOP y es totalmente compatible con versiones anteriores. He usado el Fortran 2003 a fondo y diría que fue una delicia usarlo. En algunos aspectos, Fortran 2003 todavía está detrás de C ++, pero veamos el uso. Fortran se usa principalmente para la computación numérica, y nadie usa características sofisticadas de C ++ OOP por razones de velocidad. En informática de alto rendimiento, C ++ casi no tiene un lugar adonde ir (eche un vistazo al estándar MPI y verá que C ++ ha quedado en desuso).

Hoy en día, simplemente puede hacer programación de lenguaje mixto con Fortran y C / C ++. Incluso hay interfaces para GTK + en Fortran. Hay compiladores gratuitos (gfortran, g95) y muchos excelentes comerciales.


8
¿Podría agregar una fuente, experiencia específica o instituto científico / agencia informática de alto rendimiento que se esté alejando de C ++ para proyectos futuros o reescribiendo proyectos de C ++ a otro idioma? Solo pregunto porque conozco al menos dos instituciones científicas, Sandia y CERN, que usan mucho c ++ para su modelado de alto rendimiento. Además, Sandia convirtió uno de sus software de modelado (LAMMPS) de fortran a c ++, agregando una serie de mejoras increíbles.
Zachary Kraus

77
LAMMPS está escrito en C ++ extremadamente simple que no aprovecha la mayoría de las características modernas del lenguaje. Representa el C ++ que los programadores de Fortran que conocen C escriben después de aprender C ++ 98. Esto no quiere decir que LAMMPS esté mal escrito, solo que no es el ejemplo que desea citar al abogar por C ++ en HPC.
Jeff

30

Hay varias razones por las que Fortran podría ser más rápido. Sin embargo, la cantidad que importan es tan intrascendente o puede evitarse de todos modos, por lo que no debería importar. La razón principal para usar Fortran hoy en día es mantener o ampliar las aplicaciones heredadas.

  • Palabras clave PURAS y ELEMENTALES en funciones. Estas son funciones que no tienen efectos secundarios. Esto permite optimizaciones en ciertos casos donde el compilador sabe que la misma función se llamará con los mismos valores. Nota: GCC implementa "puro" como una extensión del lenguaje. Otros compiladores también pueden hacerlo. El análisis entre módulos también puede realizar esta optimización, pero es difícil.

  • conjunto estándar de funciones que tratan con matrices, no elementos individuales. Cosas como sin (), log (), sqrt () toman matrices en lugar de escalares. Esto facilita la optimización de la rutina. La vectorización automática ofrece los mismos beneficios en la mayoría de los casos si estas funciones son en línea o incorporadas

  • Tipo complejo integrado. En teoría, esto podría permitir que el compilador reordene o elimine ciertas instrucciones en ciertos casos, pero es probable que vea el mismo beneficio con la estructura {double re, im; }; modismo utilizado en C. Sin embargo, permite un desarrollo más rápido ya que los operadores trabajan en tipos complejos en fortran.


1
"pero es probable que veas el mismo beneficio con la estructura { double re, im; };idiomática utilizada en C". Lo más probable es que los compiladores de C devuelvan esa estructura en forma sret con la pila de llamantes asignando espacio, pasando un puntero al destinatario que lo llena. Eso es varias veces más lento que devolver múltiples valores en los registros como lo haría un compilador de Fortran. Tenga en cuenta que C99 solucionó esto en el caso especial de complejo.
Jon Harrop

No estoy seguro de estar de acuerdo con su razón principal. Personalmente, me gusta usar fortran para código matemático pesado donde las matrices y las funciones matemáticas son la parte más importante del código. Pero sé con certeza que en muchas instituciones gubernamentales y bancos continúan usando fortran para mantener o extender el código heredado. Yo personalmente usé fortran para extender el código de un profesor en mi doctorado. comité escribió.
Zachary Kraus

Su afirmación, "la razón principal para usar Fortran hoy en día es mantener o ampliar las aplicaciones heredadas", es completamente errónea. Todavía no he visto ningún otro lenguaje de programación, ni siquiera remotamente, cercano a las características que Fortran proporciona, especialmente para aplicaciones matemáticas. Ya mencionó algunos de ellos, como un excelente soporte de matriz, funciones aritméticas complejas integradas, puras o elementales, y también podría nombrar más. Eso solo es suficiente para demostrar que su afirmación anterior es incorrecta.
Pap

28

Creo que el punto clave a favor de Fortran es que es un lenguaje un poco más adecuado para expresar matemáticas basadas en vectores y matrices. El problema del análisis de puntero señalado anteriormente es real en la práctica, ya que el código portátil realmente no puede suponer que puede decirle algo a un compilador. SIEMPRE hay una ventaja para los cálculos de expresión de una manera más cercana a la apariencia del dominio. C realmente no tiene matrices en absoluto, si nos fijamos bien, solo algo que se comporta de esa manera. Fortran tiene arrawys reales. Lo que facilita la compilación de ciertos tipos de algoritmos, especialmente para máquinas paralelas.

En lo profundo de cosas como el sistema de tiempo de ejecución y las convenciones de llamadas, C y Fortran moderno son lo suficientemente similares como para que sea difícil ver qué marcaría la diferencia. Tenga en cuenta que C aquí es realmente base C: C ++ es un problema totalmente diferente con características de rendimiento muy diferentes.


25

No existe un idioma que sea más rápido que otro, por lo que la respuesta correcta es no .

Lo que realmente debe preguntar es "¿el código se compila con el compilador Fortran X más rápido que el código equivalente compilado con el compilador C Y?" La respuesta a esa pregunta, por supuesto, depende de los dos compiladores que elija.

Otra pregunta que uno podría hacer sería la siguiente: "Dado el mismo esfuerzo realizado para optimizar en sus compiladores, ¿qué compilador produciría un código más rápido?" La respuesta a esto sería, de hecho, Fortran . Los compiladores de Fortran tienen ventajas certianas:

  • Fortran tuvo que competir con la Asamblea en el día en que algunos prometieron nunca usar compiladores, por lo que fue diseñado para la velocidad. C fue diseñado para ser flexible.
  • El nicho de Fortran ha sido la reducción de números. En este dominio, el código nunca es lo suficientemente rápido. Por lo tanto, siempre ha habido mucha presión para mantener el lenguaje eficiente.
  • La mayor parte de la investigación en optimizaciones de compiladores es realizada por personas interesadas en acelerar el código de números de Fortran, por lo que optimizar el código de Fortran es un problema mucho mejor conocido que optimizar cualquier otro lenguaje compilado, y las nuevas innovaciones aparecen primero en los compiladores de Fortran.
  • Biggie : C fomenta mucho más el uso de punteros que Fortran. Esto aumenta drásticamente el alcance potencial de cualquier elemento de datos en un programa en C, lo que los hace mucho más difíciles de optimizar. Tenga en cuenta que Ada también es mucho mejor que C en este ámbito, y es un lenguaje OO mucho más moderno que el Fortran77 comúnmente encontrado. Si desea un lenguaje OO que pueda generar un código más rápido que C, esta es una opción para usted.
  • Debido nuevamente a su nicho numérico, los clientes de los compiladores Fortran tienden a preocuparse más por la optimización que los clientes de los compiladores C.

Sin embargo, no hay nada que impida que alguien ponga un montón de esfuerzo en la optimización de su compilador C, y que genere un código mejor que el compilador Fortran de su plataforma. De hecho, las mayores ventas generadas por los compiladores de C hacen que este escenario sea bastante factible.


44
Estoy de acuerdo. Y debo agregar que cuando se introdujo Fortran (fue el primer lenguaje de alto nivel) a fines de los 50 y principios de los 60, muchos se mostraron escépticos sobre cuán eficiente podría ser. Por lo tanto, sus desarrolladores tuvieron que demostrar que Fortran podría ser eficiente y útil y se dispuso a "optimizarlo hasta la muerte" solo para demostrar su punto. C llegó mucho más tarde (desde principios hasta mediados de los 70) y no tenía nada que demostrar, por así decirlo. Pero en este momento, se había escrito una gran cantidad de código Fortran, por lo que la comunidad científica se adhirió a él y aún lo hace. No programo Fortran, pero he aprendido a vincular para llamar a subrutinas Fortran desde C ++.
Olumide

3
La investigación sobre la optimización del compilador ha sido más diversa de lo que parece. La historia de las implementaciones de LISP, por ejemplo, está llena de éxitos al hacer el cálculo de números más rápido que Fortran (que sigue siendo el contendiente predeterminado para desafiar). Además, una gran parte de la optimización del compilador se ha dirigido a representaciones intermedias del compilador, lo que significa que, aparte de las diferencias en la semántica (como el alias), se aplican a cualquier lenguaje de programación de una clase determinada.
Hombre de ninguna parte

2
La idea se repite mucho, pero es un poco falso decir que no hay consecuencias para la eficiencia inherente a un diseño de lenguaje de programación. Algunas características del lenguaje de programación conducen necesariamente a ineficiencias porque limitan la información disponible en el momento de la compilación.
Praxeolítico

@Praxeolitic: eso es bastante correcto (por eso me complace no haber dicho tal cosa).
TED

@TED ​​Honestamente, volviendo aquí unos meses después, no tengo idea de por qué dejé ese comentario en tu respuesta. ¿Quizás quise dejarlo en otro lugar? XP
Praxeolitic

22

Hay otro elemento en el que Fortran es diferente de C, y potencialmente más rápido. Fortran tiene mejores reglas de optimización que C. En Fortran, el orden de evaluación de una expresión no está definido, lo que permite que el compilador lo optimice; si uno quiere forzar un cierto orden, debe usar paréntesis. En C el orden es mucho más estricto, pero con las opciones "rápidas", son más relajadas y "(...)" también se ignoran. Creo que Fortran tiene un camino que se encuentra muy bien en el medio. (Bueno, IEEE hace que la vida sea más difícil ya que ciertos cambios en el orden de evaluación requieren que no ocurran desbordamientos, lo que debe ignorarse o obstaculizar la evaluación).

Otra área de reglas más inteligentes son los números complejos. No solo eso tomó hasta C 99 que C los tenía, sino que también las reglas que los gobiernan son mejores en Fortran; Como la biblioteca Fortran de gfortran está parcialmente escrita en C pero implementa la semántica de Fortran, GCC obtuvo la opción (que también se puede usar con programas C "normales"):

-fcx-fortran-rules La multiplicación y división complejas siguen las reglas de Fortran. La reducción de rango se realiza como parte de una división compleja, pero no se verifica si el resultado de una multiplicación o división compleja es "NaN + I * NaN", con un intento de rescatar la situación en ese caso.

Las reglas de alias mencionadas anteriormente son otro bono y también, al menos en principio, las operaciones de matriz completa, que si el optimizador del compilador las tiene en cuenta adecuadamente, pueden generar un código más rápido. Por el contrario, ciertas operaciones llevan más tiempo, por ejemplo, si se realiza una asignación a una matriz asignable, hay muchas comprobaciones necesarias (¿reasignar? [Función Fortran 2003], tiene los pasos de la matriz, etc.), que hacen que operación simple más compleja detrás de escena, y por lo tanto más lenta, pero hace que el lenguaje sea más poderoso. Por otro lado, las operaciones de matriz con límites y pasos flexibles hacen que sea más fácil escribir código, y el compilador generalmente optimiza mejor el código que un usuario.

En total, creo que tanto C como Fortran son casi igualmente rápidos; la elección debería ser más qué idioma le gusta más o si usar las operaciones de matriz completa de Fortran y su mejor portabilidad son más útiles, o la mejor interfaz con el sistema y las bibliotecas de interfaz gráfica de usuario en C.


¿Qué hay para "rescatar" significativamente en el caso Nan + INan? Lo que hace que los infinitos sean diferentes de NaN es que los infinitos están firmados. Las operaciones que involucran infinitos no complejos que producirían un signo confuso producen NaN y no veo ninguna razón para que los números complejos hagan lo contrario. Si uno multiplica (DBL_MAX, DBL_MAX) por (2,2), cuadra el resultado y luego cuadra ese resultado, ¿cuál debería ser el signo del resultado en ausencia de desbordamiento? ¿Cuál es uno en su lugar lo multiplica por (1.001, DBL_MAX)? Consideraría (NaN, NaN) como la respuesta correcta, y cualquier combinación de infinito y NaN como sin sentido.
supercat

14

No hay nada acerca de los lenguajes Fortran y C que hace que uno sea más rápido que el otro para fines específicos. Hay cosas sobre compiladores específicos para cada uno de estos idiomas que hacen que algunos sean más favorables para ciertas tareas que otros.

Durante muchos años, existieron los compiladores de Fortran que podían hacer magia negra en sus rutinas numéricas, haciendo muchos cálculos importantes increíblemente rápidos. Los compiladores de C contemporáneos no podían hacerlo también. Como resultado, varias grandes bibliotecas de código crecieron en Fortran. Si desea utilizar estas bibliotecas bien probadas, maduras y maravillosas, rompa el compilador Fortran.

Mis observaciones informales muestran que en estos días la gente codifica sus pesadas tareas informáticas en cualquier idioma antiguo y, si les lleva un tiempo, encuentran tiempo en algún grupo de computadoras barato. La Ley de Moore nos hace tontos a todos.


11
Casi actualizado esto. El problema es que Fortran no tiene algunas ventajas inherentes. Sin embargo, eres bastante corriente de que lo importante a tener en cuenta es el compilador, no el idioma.
TED

14

Comparo la velocidad de Fortran, C y C ++ con el clásico punto de referencia Levine-Callahan-Dongarra de netlib. La versión en varios idiomas, con OpenMP, es http://sites.google.com/site/tprincesite/levine-callahan-dongarra-vectors. El C es más feo, ya que comenzó con la traducción automática, además de la inserción de restricciones y pragmas para ciertos compiladores C ++ es solo C con plantillas STL cuando corresponde. Desde mi punto de vista, el STL es una combinación de si mejora la mantenibilidad.

Solo existe un ejercicio mínimo de la función automática en línea para ver en qué medida mejora la optimización, ya que los ejemplos se basan en la práctica tradicional de Fortran, donde se confía poco en la línea.

El compilador C / C ++ que tiene, con mucho, el uso más extendido carece de auto-vectorización, de la cual estos puntos de referencia dependen en gran medida.

Vuelva a la publicación que vino justo antes de esto: hay un par de ejemplos en los que se usan paréntesis en Fortran para dictar el orden de evaluación más rápido o más preciso. Los compiladores de C conocidos no tienen opciones para observar los paréntesis sin deshabilitar optimizaciones más importantes.


La traducción fea es necesaria para superar el problema de alias. Debe proporcionarle al compilador simulacros de variables para indicarle que las variables byref implementadas como punteros pueden optimizarse para el registro.
David

12

Soy un programador aficionado y soy "promedio" en ambos idiomas. Me resulta más fácil escribir código Fortran rápido que el código C (o C ++). Tanto Fortran como C son lenguajes "históricos" (según el estándar actual), son muy utilizados y tienen un compilador gratuito y comercial bien soportado.

No sé si es un hecho histórico, pero Fortran siente que está construido para ser paralelo / distribuido / vectorizado / lo que sea muchos núcleos. Y hoy es más o menos la "métrica estándar" cuando hablamos de velocidad: "¿escala?"

Para el crujido de CPU puro, me encanta Fortran. Para cualquier cosa relacionada con IO, me resulta más fácil trabajar con C. (de todos modos, es difícil en ambos casos).

Ahora, por supuesto, para el código de uso intensivo de matemáticas en paralelo, probablemente quiera usar su GPU. Tanto C como Fortran tienen una interfaz CUDA / OpenCL más o menos bien integrada (y ahora OpenACC).

Mi respuesta moderadamente objetiva es: si conoces ambos idiomas igualmente bien / mal, entonces creo que Fortran es más rápido porque me resulta más fácil escribir código paralelo / distribuido en Fortran que C. (una vez que entiendes que puedes escribir fortran "forma libre" y no solo el estricto código F77)

Aquí hay una segunda respuesta para aquellos que deseen denunciarme porque no les gusta la primera respuesta: ambos idiomas tienen las características necesarias para escribir código de alto rendimiento. Por lo tanto, depende del algoritmo que esté implementando (¿CPU intensiva? ¿Intensiva? ¿Intensiva en memoria?), El hardware (¿CPU única? ¿Multinúcleo? Tanto C como Fortran tienen un increíble compilador. (Estoy realmente sorprendido por lo avanzados que son los compiladores de Fortran, pero también lo son los compiladores de C).

PD: me alegra que hayas excluido específicamente las bibliotecas porque tengo muchas cosas malas que decir sobre las bibliotecas GUI de Fortran. :)


11

Estuve haciendo algunas matemáticas extensas con FORTRAN y C durante un par de años. Según mi propia experiencia, puedo decir que FORTRAN a veces es realmente mejor que C, pero no por su velocidad (se puede hacer que C funcione tan rápido como FORTRAN usando el estilo de codificación apropiado) sino por bibliotecas muy bien optimizadas como LAPACK, y por Gran paralelización. En mi opinión, es muy difícil trabajar con FORTRAN, y sus ventajas no son lo suficientemente buenas como para cancelar ese inconveniente, por lo que ahora estoy usando C + GSL para hacer cálculos.


10

Cualquier diferencia de velocidad entre Fortran y C será más una función de las optimizaciones del compilador y la biblioteca matemática subyacente utilizada por el compilador particular. No hay nada intrínseco en Fortran que lo haga más rápido que C.

De todos modos, un buen programador puede escribir Fortran en cualquier idioma.


@ Scott Clawson: tienes -1 y no sé por qué. Hice +1 para remediar esto. Sin embargo, algo a tener en cuenta es que Fortran ha existido por más tiempo que muchos de nuestros padres. Mucho tiempo dedicado a optimizar la salida del compilador: D
user7116

Estoy de acuerdo. Acababa de publicar una respuesta muy similar en paralelo.
Alto Jeff

El problema del alias de puntero en C ha sido planteado por otros, pero hay varios métodos que el programador puede usar en compiladores modernos para lidiar con eso, así que todavía estoy de acuerdo.
Alto Jeff

1
@Kluge: "No hay nada intrínseco en Fortran que lo haga más rápido que C". Alias ​​de puntero, devolución de valores compuestos en registros, construcciones numéricas de nivel superior incorporadas ...
Jon Harrop

9

No he escuchado que Fortan es significativamente más rápido que C, pero podría ser concebible que en ciertos casos sería más rápido. Y la clave no está en las características del lenguaje que están presentes, sino en aquellas que (generalmente) están ausentes.

Un ejemplo son los punteros en C. Los punteros en C se usan prácticamente en todas partes, pero el problema con los punteros es que el compilador generalmente no puede saber si apuntan a las diferentes partes de la misma matriz.

Por ejemplo, si escribió una rutina estricta que se parece a esto:

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

El compilador tiene que funcionar bajo el supuesto de que d y s podrían estar superpuestos a las matrices. Por lo tanto, no puede realizar una optimización que produzca resultados diferentes cuando las matrices se superponen. Como era de esperar, esto restringe considerablemente el tipo de optimizaciones que se pueden realizar.

[Debo señalar que C99 tiene una palabra clave "restringir" que explícitamente le dice a los compiladores que los punteros no se superponen. También tenga en cuenta que el Fortran también tiene punteros, con semánticas diferentes de las de C, pero los punteros no son ubicuos como en C.]

Pero volviendo al tema C vs.Fortran, es concebible que un compilador Fortran sea capaz de realizar algunas optimizaciones que podrían no ser posibles para un programa C (escrito directamente). Así que no me sorprendería demasiado el reclamo. Sin embargo, espero que la diferencia de rendimiento no sea tanto. [~ 5-10%]


9

Rápido y simple: Ambos son igualmente rápidos, pero Fortran es más simple. Lo que es realmente más rápido al final depende del algoritmo, pero de todos modos no hay una diferencia de velocidad considerable. Esto es lo que aprendí en un taller de Fortran en el centro de informática de alto rendimiento Stuttgard, Alemania, en 2015. Trabajo con Fortran y C y comparto esta opinión.

Explicación:

C fue diseñado para escribir sistemas operativos. Por lo tanto, tiene más libertad de la necesaria para escribir código de alto rendimiento. En general, esto no es un problema, pero si uno no programa con cuidado, puede ralentizar fácilmente el código.

Fortran fue diseñado para la programación científica. Por esta razón, es compatible con la escritura rápida de sintaxis de código, ya que este es el propósito principal de Fortran. A diferencia de la opinión pública, Fortran no es un lenguaje de programación obsoleto. Su último estándar es 2010 y los nuevos compiladores se publican regularmente, ya que la mayoría del código de alto rendimiento está escrito en Fortran. Fortran admite además funciones modernas como directivas de compilación (en pragmas C).

Ejemplo: Queremos dar una estructura grande como argumento de entrada a una función (fortran: subrutina). Dentro de la función, el argumento no se altera.

C admite ambos, llamada por referencia y llamada por valor, que es una característica útil. En nuestro caso, el programador podría usar accidentalmente la llamada por valor. Esto ralentiza las cosas considerablemente, ya que la estructura debe copiarse primero en la memoria.

Fortran trabaja solo con llamada por referencia, lo que obliga al programador a copiar la estructura a mano, si realmente quiere una operación de llamada por valor. En nuestro caso, fortran será automáticamente tan rápido como la versión C con llamada por referencia.


¿Se puede escribir una aplicación paralela nativa en C (es decir, sin llamar a ninguna biblioteca)? No. ¿Puedes escribir una aplicación paralela nativa en Fortran? Sí, de diferentes maneras. Ergo, Fortran es "más rápido". Aunque, para ser justos, en 2010, cuando escribió su comentario, el soporte para las funciones paralelas do y co-array de Fortran probablemente no estaba tan extendido como ahora.
Mali Remorker

@MaliRemorker Escribió esto en 2016, no en 2010.
Kowalski

La sobrecarga de crear procesos paralelos no es, en mi opinión, el factor más relevante para un lenguaje de programación que se llama 'rápido'. Más relevantes son las consideraciones prácticas, como una paz de código no performante. Por lo tanto, no ayuda nada si ahorra tiempo una vez (al crear el proceso paralelo) y luego lo desperdicia en múltiples núcleos. El término 'rápido' también debería considerar códigos no paralelos. Por esta razón, no puedo ver un argumento en contra de mi punto. ¿Quizás tu comentario fue una respuesta independiente?
Markus Dutschke

8

En general, FORTRAN es más lento que C. C puede usar punteros de nivel de hardware que permiten al programador optimizar a mano. FORTRAN (en la mayoría de los casos) no tiene acceso a hacks de direccionamiento de memoria de hardware. (VAX FORTRAN es otra historia). He usado FORTRAN de vez en cuando desde los años 70. (De Verdad.)

Sin embargo, a partir de los años 90, FORTRAN ha evolucionado para incluir construcciones de lenguaje específicas que pueden optimizarse en algoritmos inherentemente paralelos que realmente pueden gritar en un procesador multinúcleo. Por ejemplo, la vectorización automática permite que múltiples procesadores manejen cada elemento en un vector de datos simultáneamente. 16 procesadores - vector de 16 elementos - el procesamiento tarda 1/16 del tiempo.

En C, debe administrar sus propios subprocesos y diseñar su algoritmo con cuidado para el procesamiento múltiple, y luego usar un montón de llamadas API para asegurarse de que el paralelismo ocurra correctamente.

En FORTRAN, solo tiene que diseñar su algoritmo cuidadosamente para el procesamiento múltiple. El compilador y el tiempo de ejecución pueden manejar el resto por usted.

Puedes leer un poco sobre High Performance Fortran , pero encontrarás muchos enlaces muertos. Es mejor leer acerca de la programación paralela (como OpenMP.org ) y cómo FORTRAN lo admite.


66
@ S.Lott: No podía imaginar lo horrible que tendría que verse el código C para hacer tan bien como simplemente escribió Fortran para la mayoría de los códigos que tenemos aquí ... y soy un programador en C. Obtendrá un mejor rendimiento de un código más simple en Fortran. No es que usted o yo no podamos encontrar un contraejemplo. : D
user7116

2
@ Greg Rogers: Tendrás que abordar tu problema con la gente de Vectorización de Fortran, no conmigo. Solo estoy informando lo que leí. polyhedron.com/absoftlinux
S. Lott

2
-1 // "Generalmente FORTRAN es más lento que C. Esto es cierto para casi todo". ¿por qué? // un argumento basado en la facilidad de usar subprocesos múltiples en Fortran vs C no dice algo sobre el rendimiento.
steabert 05 de

44
@ S.Lott: "el subprocesamiento múltiple solo existe para el rendimiento". Err, no.
Jon Harrop

44
@ S.Lott: "El uso de punteros por parte de C casi a nivel de hardware permite que C sea más rápido que Fortran". Err, no
Jon Harrop

5

El código más rápido no está realmente a la altura del lenguaje, es el compilador para que pueda ver el "compilador" ms-vb que genera un código de objeto hinchado, más lento y redundante que está unido dentro de un ".exe", pero powerBasic genera demasiado mejor código El código objeto creado por un compilador C y C ++ se genera en algunas fases (al menos 2), pero por diseño, la mayoría de los compiladores Fortran tienen al menos 5 fases, incluidas optimizaciones de alto nivel, por lo que Fortran siempre tendrá la capacidad de generar código altamente optimizado. Entonces, al final, el compilador no es el idioma que debe pedir, el mejor compilador que conozco es el compilador Intel Fortran porque puede obtenerlo en LINUX y Windows y puede usar VS como IDE, si está buscando un compilador tigh barato que siempre puede transmitir en OpenWatcom.

Más información sobre esto: http://ed-thelen.org/1401Project/1401-IBM-Systems-Journal-FORTRAN.html


3

Fortran tiene mejores rutinas de E / S, por ejemplo, la función implícita do brinda flexibilidad que la biblioteca estándar de C no puede igualar.

El compilador Fortran maneja directamente la sintaxis más compleja involucrada, y como tal sintaxis no se puede reducir fácilmente a la forma de pasar argumentos, C no puede implementarla de manera eficiente.


1
¿Tiene puntos de referencia que muestran a Fortran superando a C por E / S?
Jeff

3

Usando estándares modernos y compilador, ¡no!

Algunas de las personas aquí han sugerido que FORTRAN es más rápido porque el compilador no necesita preocuparse por el alias (y, por lo tanto, puede hacer más suposiciones durante la optimización). Sin embargo, esto se ha tratado en C desde el estándar C99 (creo) con la inclusión de la palabra clave restrict. Lo que básicamente le dice al compilador, que dentro de un ámbito dado, el puntero no tiene alias. Además, C permite una aritmética de puntero adecuada, donde cosas como el alias pueden ser muy útiles en términos de rendimiento y asignación de recursos. Aunque creo que la versión más reciente de FORTRAN permite el uso de punteros "adecuados".

Para implementaciones modernas, C general supera a FORTRAN (aunque también es muy rápido).

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

EDITAR:

Una crítica justa de esto parece ser que la evaluación comparativa puede estar sesgada. Aquí hay otra fuente (relativa a C) que pone el resultado en más contexto:

http://julialang.org/benchmarks/

Puede ver que C generalmente supera a Fortran en la mayoría de los casos (nuevamente vea las críticas a continuación que también se aplican aquí); Como han dicho otros, la evaluación comparativa es una ciencia inexacta que se puede cargar fácilmente para favorecer un idioma sobre otros. Pero sí pone en contexto cómo Fortran y C tienen un rendimiento similar.


44
Sería tonto creer cualquier cosa sobre Fortran en una publicación que asume que todavía es FORTRAN. Eso cambió hace más de 25 años. Esas pruebas no pueden comparar idiomas, porque usan compiladores de diferentes proveedores, aunque tanto Intel como GCC tienen compiladores para C y Fortran. Por lo tanto, esas comparaciones no valen nada.
Vladimir F

2

Fortran puede manejar la matriz, especialmente las matrices multidimensionales, de manera muy conveniente. Cortar elementos de una matriz multidimensional en Fortran puede ser mucho más fácil que eso en C / C ++. C ++ ahora tiene bibliotecas que pueden hacer el trabajo, como Boost o Eigen, pero están detrás de todas las bibliotecas externas. En Fortran estas funciones son intrínsecas.

Que Fortran sea más rápido o más conveniente para el desarrollo depende en gran medida del trabajo que necesita terminar. Como persona de computación científica para geofísica, hice la mayor parte de la computación en Fortran (me refiero a Fortran moderno,> = F90).


1
Y también si Fortran es más rápido también depende de: el compilador que use (¡es importante!), Para los trabajos de cálculo si aplica la paralelización adecuada al código y cómo se escribe su código.
Kai

1

Esto es más que algo subjetivo, porque entra en la calidad de los compiladores y más que cualquier otra cosa. Sin embargo, para responder más directamente a su pregunta, hablando desde el punto de vista del lenguaje / compilador, no hay nada sobre Fortran sobre C que lo haga inherentemente más rápido o mejor que C. Si está haciendo operaciones matemáticas pesadas, todo se reducirá a la calidad del compilador, la habilidad del programador en cada lenguaje y las bibliotecas de soporte matemático intrínseco que soportan esas operaciones para determinar cuál será más rápido para una implementación dada.

EDITAR: Otras personas como @Nils han planteado el buen punto sobre la diferencia en el uso de punteros en C y la posibilidad de alias que tal vez hace que las implementaciones más ingenuas sean más lentas en C. Sin embargo, hay formas de lidiar con eso en C99 , mediante indicadores de optimización del compilador y / o cómo se escribe realmente el C. Esto está bien cubierto en @Nils answer y los comentarios posteriores que siguen a su respuesta.


Suena como una prueba de referencia de un algoritmo. ¿Qué lleva menos tiempo, FORTRAN o C? No me suena subjetivo. Quizás me estoy perdiendo algo.
S.Lott

1
Discrepar. Estás comparando los compiladores, no los idiomas. Creo que la pregunta original es si hay algo sobre el IDIOMA que lo hace inherentemente mejor. Otras respuestas aquí están abordando algunas de las sutiles diferencias cuestionables, pero creo que la mayoría estamos de acuerdo en que están en el ruido.
Alto Jeff

Este no es el análisis O (n) de algoritmos. Es el rendimiento. No veo cómo el rendimiento puede ser un concepto hipotético de implementación independiente. Supongo que me estoy perdiendo algo.
S.Lott

1
-1: "no hay nada sobre Fortran sobre C que lo haga inherentemente más rápido o mejor que C". Err, no.
Jon Harrop

0

La mayoría de las publicaciones ya presentan argumentos convincentes, por lo que solo agregaré los proverbiales 2 centavos a un aspecto diferente.

Ser fortran más rápido o más lento en términos de poder de procesamiento al final puede tener su importancia, pero si lleva 5 veces más tiempo desarrollar algo en Fortran porque:

  • carece de una buena biblioteca para tareas diferentes de la suma de números pura
  • carece de una herramienta decente para la documentación y las pruebas unitarias
  • Es un lenguaje con muy baja expresividad, disparando el número de líneas de código.
  • tiene un manejo muy pobre de las cuerdas
  • tiene una gran cantidad de problemas entre diferentes compiladores y arquitecturas que te vuelven loco.
  • tiene una estrategia de E / S muy pobre (LEER / ESCRIBIR archivos secuenciales. Sí, existen archivos de acceso aleatorio, pero ¿los vio alguna vez utilizados?)
  • No fomenta las buenas prácticas de desarrollo, la modularización.
  • falta efectiva de un compilador de código abierto totalmente estándar y totalmente compatible (tanto gfortran como g95 no admiten todo)
  • interoperabilidad muy pobre con C (desgarro: un guión bajo, dos guiones bajos, sin guión bajo, en general un guión bajo pero dos si hay otro guión bajo. y simplemente no permita profundizar en los bloques COMUNES ...)

Entonces el problema es irrelevante. Si algo es lento, la mayoría de las veces no puede mejorarlo más allá de un límite determinado. Si quieres algo más rápido, cambia el algoritmo. Al final, el tiempo de la computadora es barato. El tiempo humano no lo es. Valorar la elección que reduce el tiempo humano. Si aumenta el tiempo de la computadora, es rentable de todos modos.


3
rechazado porque aunque plantea puntos interesantes que se suman a una discusión de los beneficios / inconvenientes de fortrans en comparación con otros idiomas (con los que no estoy completamente de acuerdo), esta no es realmente una respuesta a la pregunta ...
steabert

@steabert: de hecho, dijeI will just add the proverbial 2 cents to a different aspect
Stefano Borini, el

1
+1 de mi parte por alguna respuesta no quisquillosa. Como dijiste, Fortran podría ser más rápido en algunas tareas raras (no he visto ninguna personalmente). Pero la cantidad de tiempo que pierde para mantener un lenguaje inmanejable arruina cualquier ventaja posible.
André Bergner

10
-1. Parece que estás pensando en Fortran en términos de F77. Eso fue reemplazado por F90, F95, F03 y F08.
Kyle Kanos

44
Votado negativamente porque habla exclusivamente de un lado de una compensación. La velocidad de desarrollo puede ser importante para la mayoría de la programación general, pero eso no la convierte en la única compensación válida. Los programadores de Fortran son a menudo científicos / ingenieros que valoran la simplicidad del lenguaje (FORmula TRANslation es extremadamente fácil de aprender y dominar. C / C ++ no lo es ), las excelentes bibliotecas (a menudo utilizadas desde otros idiomas) y la velocidad (por ejemplo, simulaciones climáticas que toman días en Fortran, pero meses si se escriben completamente en otros idiomas).
BraveNewCurrency

-3

Fortran tradicionalmente no establece opciones como -fp: estricto (que ifort requiere para habilitar algunas de las características en USE IEEE_arithmetic, una parte del estándar f2003). Intel C ++ tampoco establece -fp: estricto por defecto, pero eso es necesario para el manejo de ERRNO, por ejemplo, y otros compiladores de C ++ no hacen que sea conveniente apagar ERRNO u obtener optimizaciones como la reducción de simd. gcc y g ++ me han requerido configurar Makefile para evitar usar la combinación peligrosa -O3 -ffast-math -fopenmp -march = native. Además de estos problemas, esta pregunta sobre el rendimiento relativo se vuelve más exigente y dependiente de las reglas locales sobre la elección de compiladores y opciones.


Las actualizaciones recientes de gcc corrigieron el problema con la combinación de Openmp y fast-math.
tim18

Esta respuesta es realmente sobre los usuarios que no entienden los indicadores predeterminados para sus compiladores, no los idiomas en sí.
Jeff
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.