8 ms·
What Fortran does better than C-like languages
- jleyank 5y agoAt least back in the mini super era, Fortran was (far) easier for the compiler to optimize than C. Yeah, you could add all sorts of #pragma indicating that pointer/array are not overlapping in memory but that equivalence was a problem. But then, trying to do I/o in Fortran was annoying so lots of compute codes ended up with c front ends.
- pjmlp 5y agoStill is. Trying to outperform Fortran relies on C developers putting the right annotations on the right places and never get them misplaced, otherwise it will trigger UB.
- adgjlsfhk1 5y agoIn my opinion, Julia is much better for numeric performance than C or Fortran. Real macros mean that you don't have to use a janky preprocessor (or a separate programming language) to generate optimal code, and multiple dispatch means you don't need to give your functions awful names (looking at you cgbtrf) and instead can just name them for what they do. (Also, Julia gives you easy automatic differentiation and gpuification)
- klodolph 5y agoThe awful names are from a six-character limit somewhere. I'm curious why you would want multiple dispatch. Seems to me like either longer names or single dispatch would be enough. In "cgbtrf", the first three letters just tell you what kind of matrix are the input... "cgb" being a complex-valued band matrix. That leaves you only three letters to say what the function does.
- adgjlsfhk1 5y agowith multiple dispatch, this function would just be lu. Multiple dispatch means that all the functions that add things can just be called +, and all the ones that compute lu factorizations can be lu, and which specific version gets called is all handled by the type system. If I call lu on a complex banded matrix, it will dispatch to the method optimized for that without me having to care about what that is. This makes writing generic code much easier because you don't have to write a separate copy of your function for each new datatype you want to support.
- pjmlp 5y agoSo like Fortran generics.
- adgjlsfhk1 5y agoNot really, Fortran is inching it's way towards generics, but doesn't actually have them in a usable form yet.
- pjmlp 5y agoParameterized derived types seem good enough for what Fortran is used for.
- adgjlsfhk1 5y agoThey are powerful enough to express functions that only depend on one argument, but how would you use them to encode the types of both arguments for matrix multiplication?
- pjmlp 5y agoLike this? https://www.pgroup.com/blogs/posts/f03-oop-part3.htm https://www.pgroup.com/blogs/posts/f03-oop-part3.htm
- pjmlp 5y agoEventually, note that you should compare it against latest ISO Fortran standard per commercial compilers, not what gfortran is capable of.
- sampo 5y ago> multiple dispatch means you don't need to give your functions awful names (looking at you cgbtrf) and instead can just name them for what they do. Fortran has ad-hoc polymorphism, and 63 characters maximum length for names. These should be enough to keep the user happy in this use case. (The programmer still needs to write separate code for each version of input types.)
- cudder 5y agoWhy is fortran so much more efficient (or easier to optimize)?
- pjmlp 5y agoBecause it was designed for mathematics from the ground up. So the language has built-in optimization for linear algebra kind of math since decades, doesn't rely on pointers for basic data structures and type system prevents aliasing by default.
- gnufx 5y agoThe language doesn't specify optimization, though it has features for optimizers to take advantage of, and the classic loop optimizations were introduced in Fortran H if I remember correctly. The storage association rules aren't in the type system; you can write code that violates them, and many people did, but perhaps fewer now.
- jejones3141 5y agoSee the section of Coders at Work where the author interviews Frances Allen.
- gnufx 5y agoWell, Fortran relies on you obeying the storage association rules that people regularly used to assure me didn't exist.
- legerdemain 5y agoA bit odd of the author to make claims about "C-like languages" and then focus mostly on C. For example, Java does have loop labels. Further afield, Groovy has a very flexible switch statement which accepts literals, ranges, predicates, and types. In Groovy, you can also index into list literals with ranges and negative indexes.
- hpcjoe 5y agoFortran used to get lots of hate from the C-like crowd. Maybe it still does. This said, it is a modern, very high performance computing language. It is easy to, as the article notes, adapt the language to fit the algorithm, rather than doing the reverse which C/C++/etc. demand. The only other language that I am aware of like that is Julia. Julia has a REPL built in, and you need to use PackageCompiler.jl to compile AOT code. Then again fortran has a nascent REPL[1]. [1] https://lfortran.org/ https://lfortran.org/
- adgjlsfhk1 5y agoHonestly, I think fortran is way too far behind Julia at this point to be able to catch up. The work on LFortran is really ambitious and badly needed for the language, but it was needed 20 years ago. Once you factor in the fact that Fortran isn't expecting generics until the end of the decade, and has no real plans for solid GPU support, and I don't see it being enough to keep up with more modern languages.
- j_not_j 5y agoThe OpenMP project provides GPU support for the #pragmas which parallelize both C and Fortran 90 codes on SMP machines. (Note: not OpenMPI). See https://www.openmp.org/blog/openmp-api-speeds-up-autonomous-driving-codes/ https://www.openmp.org/blog/openmp-api-speeds-up-autonomous-... for a description of an example application of this. Both GNU and Clang support OpenMP pragmas.
- Aisen8010 5y agoThe example 'exiting a nested loop' was weird. C has support to 'goto', C's version would look like the Fortran's code.
- asddubs 5y agowell, you'd label the end of the loop rather than the beginning, which is mildly messier, but yeah
- nmilo 5y agoWhat a weird post. There's so many cool things Fortran does better than C-like languages, but instead the post focuses on superficial syntax like labelled loops and dangling elses. The labelled loops thing particularly irks me because it's a so often repeated qualm about C yet it's performing the exact same function as a goto--so why not use a goto?
- asddubs 5y agoyeah I was expecting stuff like not allowing aliasing, which allows the compiler to optimize functions better
- nusaru 5y agoI guess some people are afraid to use a gun for fear that they might shoot their foot—or that someone else will. I think goto’s are useful.
- rightbyte 5y agoThere is a dogmatic contempt for goto:s. Like people who use them are stupid or something and obviously doing it wrong. I think the underlying reason is that it is annoying to write tree walking interpreters and implement goto:s. (How do you even do that?). So the prominent CS folks at the time just dismissed goto:s instead by bullying user to submission.
- scambier 5y agoThe contempt is justified. `goto`s break the flow and make the code harder to read and reason about, and thus make it easier to introduce bugs. It's an instruction that's almost never _needed_ today, because there is always a better structure to use instead. I only use it in Lua, to compensate for a lack of `continue` in loops.
- cyberpunk 5y agocybrpnk:~/src/linux$ grep -rniE 'goto\W+.*;' . | grep -E '\.[c|h]:' | wc -l 182044 Sure.. I mean.. 'almost'
- anonymousiam 5y agoOne of the first bits of FORTRAN mischief I learned (on a HP1000 A900) was because values are passed to subroutines by reference, the subroutine could alter an argument and the alteration would persist back to the parent(s). This could even be done to constants! Because the HP macro (microcode) architecture did not have immediate arguments, all loads are from initialized memory. Thus if you pass a constant (such as "1") to a subroutine that alters its value, all subsequent use of "1" in the program would no longer be 1.
- sampo 5y agoThe conventional, idiomatic style is to mark the `intent` of your function/subroutine arguments. Then the compiler can check that you don't attempt to mutate input variables, or read the output variables. pure subroutine mean_and_std(vec, mean, std) real, intent(in) :: vec(:) real, intent(out) :: mean, std mean = sum(vec) / size(vec) std = sqrt(sum((vec - mean)**2) / size(vec)) end subroutine
- anonymousiam 5y agoThanks! Apparently the "intent" attribute was added in FORTRAN 2003. This was about 20 years too late for the A900. http://www.hpmuseum.net/display_item.php?hw=594 http://www.hpmuseum.net/display_item.php?hw=594
- sampo 5y ago> Apparently the "intent" attribute was added in FORTRAN 2003. It was added in Fortran 90.
- anonymousiam 5y agoEither way, it was too late for me. The A900 FORTRAN compiler did "Extended FORTRAN 77" and the "card" at the top of each source file was: FTN7X
- gnufx 5y ago
- sampo 5y ago> <strong>loop1</strong>: do i = 1, 10 Those "strong" tags are, obviously, a mistake in the webpage html code, and not part of Fortran syntax.
- kangalioo 5y agoThanks for the clarification. I really thought Fortran wanted to borrow from XML there haha
- sundarurfriend 5y ago"strong" loops - for when you want the CPU to really focus on this loop.
- baybal2 5y ago> In C-like languages exiting from a deeply nested loop isn’t exactly trivial (without the use of goto, so don’t even go there). What's wrong with goto to do exactly what it's supposed to do? You can of course wrap loop content into functions, and maybe the compiler will "out-optimize" that, but you will never get the performance of loops in a single function, nor you can conditionally jump from middle of one loop into another.
- lentil_soup 5y ago>> for numerical computation there is likely no faster language What does the author mean by this? How can you get faster than any other compiled language like C where you can check the generated assembly? Does the Fortran compiler do anything special that others don't?
- cygx 5y agoFortran forbids aliasing. This gave Fortran compilers an edge before the introduction of restrict with C99. Not sure if there still exist semantic differences affecting optimizability to this day - perhaps things related to automatic vectorization?
- jcranmer 5y agoOne big issue is that C doesn't have guard rails against overflows within an object. For example, if you have an array `int a[3][3];`, `a[0][4]` is a perfectly legal way to refer to `a[1][0]`, because it's all within the same object.
- eterevsky 5y agoIf I'm not mistaken, C has weaker guarantees over which pointers can point to what memory. It means that it has to dump the variables into memory more often to make sure that pointers dereferencing is correct.
- deleted 5y ago[deleted]
- gnufx 5y agoWith GCC (now the GNU Compiler Collection) for instance, it's the same compiler for C and Fortran, just different front ends. The statement isn't useful, anyway, as it doesn't say compiled Fortran will be faster. Given the complex type, and restrict in current C, the main feature of Fortran that might help is arrays.
- gnufx 5y agoYou might consider that backwards; John Levine, comp.compilers moderator, referred to C as a Fortran-like language.
- eterevsky 5y agoIt looks like C-like language in this context is literally C. Even C++ has some of the features listed here, like array slicing. If you consider Rust "C-like", it has solutions for all the mentioned issues.
- jbverschoor 5y agoStopped reading after the breaks. You can break to labels. Even in Java. It’s like goto A better design would be to just return from a function
- sischoel 5y agoC and C++ do not have labeled breaks - Java indeed has. But of course you are right, that one could just use goto for C/C++.
- moomin 5y agoIt’s amazing how much effort has gone into making C compilers achieve the kind of performance that was routine for FORTRAN. The reason, ironically, is that FORTRAN didn’t suffer from the aliasing ambiguity that C does.