30 years on, the old adage remains the same: develop on Windows when you have to, on Linux when you can.
Thank you very much! @themos
The thing is, we need to develop a package for users in windows, mac, and linux. Therefore I have to consider the performance on windows.
Despite gfortran’s performance on windows is not the same as in linux, Intel fortran’s performance is very consistent across these 3 platforms.
This isn’t just a problem with Fortran; I know a number of other languages appear to run less efficiently on Windows. It is hard enough to get a port; if you want performance you will likely use native windows interfaces. Perhaps Windows subsystem for Linux might help.
I second that WSL2 is a good choice. Actually most of my Fortran codes run faster on WSL2 than native Windows environment.
Thank you @R_cubed @han190, yes I know.
Thing is, I am not running the program for my own.
We are develop an R package which will call the Fortran compiler and compile files and run program on the user’s PC. The users just need to install the R package and fortran compiler, and they are just very regular users and it is almost impossible to ask them to install WSL.
So the most easy/straightforward way is just to make the gfortran on windows run as fast as on linux. Or we may simply use intel OneAPI instead.
Also because that we are develop the package, I am seeking easy ways to install Fortran packages on users’ PC. So they do not need to do anything. We install the packages automatically for them, and use the package, compile, and run the program.
You know, like developing an software, and the user only need to click the installation exe file and install and that is all.
Very easy, a very small code (many lines are commented actually). On windows, if you installed gfortran and make, then you just need to download the files in one folder, then do
If I use Intel Fortran on windows, it took 0.5s, gfortran tool 3s.
On Ubuntu both intel and gfortran took 0.5s.
I tried to use gprof on windows with gfortran, but it always give me empty out file.
I always find on Ubuntu, gfortran’s performance is similar with Intel Fortran.
But on windows, gfortran, at least for my code, is basically always several times slower than intel Fortran. If someone have the interest to have a quick look and identify the issue it will be greatly appreciated!
By the way, does anyone else have similar issue?
ie, the same code, using gfortran on windows it is several times slower than using gfortran on Ubuntu.
You can try a trick:
1 Create a ramdisk
2 Move everything to the ramdisk and run your code there
3 Move everything back
It is trivial to create a ramdisk in linux . I have never done it in Windows, but it seems you can as well:
Thanks @conradoat !
Eh, yeah, but I think it problem seems is not caused by the I/O.
I like the idea is ramdisk actually .
I previous thought that if I install latex in ramdisk, and then compile latex files there, things will be lightning fast! But it turned out to be the speed of compiling latex on randisk is the same as compiling it on my ssd, lol. Because on ramdisk is file system is still NTFS.
Therefore I realize that Linux files system perhaps is much faster than windows’s NTFS. It seems no matter how fast or how high IOPS the SSD is, on windows file system it is just cannot reach its potential.
@CRquantum you can try to gather together at most I/O ops in your code. That is something that slows down everything.
But I would advise you to avoid running on windows, if you can.
Thanks @conradoat .
Eh, yeah, I have turned off I/O completely (the only write to a file, is just at the end when computation is done, it write to a very small file). The timing did not improved.
Now, the only I/O I have is just
write(6,*) which is write to the screen.
Eh, are you suggesting turn off all the
I am developing a package in Fortran and I hope it can be used on Win/Linux/Mac. Letting the user installing gfortran and Make on windows is a very convenient choice. Otherwise user need install Intel OneAPI which is also great but does not really optimize for Apple M1.
So I think if gfortran works fine on Win/Linux/Mac, it can be great.
But the issue of gfortran I have met on windows is that its performance is several times slower than on Linux.
Also, gfortran/gcc seems still some compatibility issue with M1 chip. For example, if use a pointer to point to a function/subroutine, gfortran seems can only work with
-Og flag. With more than that optimization it will cause some error on M1 chip.
Blockquote Eh, are you suggesting turn off all the
Yes if you can. But from what you say, it seems that the I/O is not the problem.
Thanks @conradoat .
The IO or wirte(6,*) seems is really not the problem. Even if I turned them all off, timing is the same, on windows gofrtran took 3s, intel took 0.5s.
Have you looked at the assembly language produced? I strongly suspect that the answer is there.
@CRQuantum, I think that many of the statements and conclusions stated in the various posts in this thread are unfair to Gfortran. Not much has been said about which versions of Gfortran were used on Windows, and which emulation layer/DLL support infrastructure was used.
I am attempting to make amends.
A brief scan of your sources made me suspect that it uses 8-byte integers in many places where 4-byte integers would have sufficed. This choice, naturally, affects performance, but I did not want to spend any time to alter this aspect of the code.
I took your Gitlab sources, and commented out most of the WRITE statements, until the program produced just 16 lines of output. Here are the run times on my NUC (small box PC with low power laptop processor i7-10710U, laptop memory, on a ramdisk, balanced power setting, Win11-64).
Ifort 2021.5, /O2 : 0.55 s -same-, but /fast : 0.38 s Cygwin Gfortran 11.2, -O2 : 0.79 s Eq.com Gfortran 12.0, -O2 : 2.76 s
I strongly suspected that the difference in the Gfortran times is attributable to Cygwin using (naturally) Cygwin1.DLL rather than the MinGW DLLs. If so, most of the slowdown that you noticed is attributable not to the compiler but to the runtime (which is also used by GCC, G++, etc.). I ran a test to settle my suspicion. I used Cygwin Gfortran to produce .o files, and linked the .o files using the MinGW Gfortran. The resulting a.exe took 2.8 s. This proves that there can be drastic differences in run times of Fortran programs depending on which versions of the GCC RTL are used. We may note in this connection that MinGW was last updated in 2013, whereas Cygwin was updated just two months ago.
You also wrote that Gprof failed to give you profile output. Here is part of the output that I obtained from Cygwin Gprof:
Flat profile: Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls ms/call ms/call name 38.24 0.26 0.26 10198404 0.00 0.00 __samplers_MOD_pyq_i_o 35.29 0.50 0.24 _mcount_private 8.82 0.56 0.06 3999800 0.00 0.00 __random_MOD_randn 5.88 0.60 0.04 __fentry__ 2.94 0.62 0.02 208 0.10 0.10 __random_MOD_gaussian 2.94 0.64 0.02 100 0.20 0.50 __samplers_MOD_metroplis_gik_k_more_o_log 2.94 0.66 0.02 51 0.39 5.87 __samplers_MOD_prep 2.94 0.68 0.02 exp
If you skip the line for _mcount, which is the profiling routine itself, you may note that the biggest time consumed is in function PYQ_I, and that function accounts for over a third of the run time.
You may attempt to modify your code to reduce the number of calls to PYQ_I, or to make it a vector function instead of a scalar, if that is feasible. Secondly, as I mentioned earlier, see if you can be more judicious in using 8-byte integer variables.
Optimize? Intel OneAPI Fortran compilers generate code for X86/X64 processors. They do not target ARM at all.
I have not used an Apple computer for years. From what I have read, Apple M computers provide an emulator/translator/converter “Rosetta-?” that allows running executables that target Apple’s older X64 computers.
Thank you very much @mecej4 !
I totally agree with you. I do believe it is caused by some dll stuff in windows caused the problem. But I just do not know how to fix. Do you know how to fix that?
I am the only one in the place I work insisting using Fortran.
Before I came, they almost want to give up Fortran and switch to Julia (I have a Julia version of the code as well, but it is 3 times slower, on windows Julia costs 1.5s. But still better than gfortran’s 3s).
They told me that, after many years of wrestling with gfortran, they are a little tired of gfortran. Because different users have different versions gfortran, the same code sometimes work on some versions of gfortran, sometimes not. The performance of gfortran on windows is not consist with on Mac or Linux. You know, as a user, they do not care and do not know the problem is caused by DLL or gofrtran. All they know is that they installed gfortran, and compile and build the code, and the code is slow. So they will just blame gfortran.
I thought they have problems with gfortran, that is perhaps their code is not written good enough, and I never thought gfortran have any problems in any way.
I showed them fast algorithm using modern Fortran with intel OneAPI, now they are considering Fortran again. Especially because Intel’s OneAPI is free now and works fine on windows and Linux.
Again, I want to make code perform consistent on WIn/Linux/Mac, I see gfortran has the potential to be a very good lightweight choice for all the three platforms.
But the slowness problem currently I have with gfortran on windows, really and deeply bothers me very much.
I see you use cygwin64 on windows 10, and that gfortran cost 0.79s, that is about right.
I wonder how did you achieve that?
I mean I installed cygwin64 and installed gfortran 11.2.0 there, then I compile and run my code there, but I still get slow speed like 2.9s,
The real problem is, how to make my code on windows, using gfortran, roughly the same speed as gfortran run on Ubuntu? Do you know how to fix that? What gfortran for windows should I use? I have installed all the possible gfortran version on windows, and it seems they just perform 6x slower on windows than on Linux.
I really hope there is a way to make gfortran’s speed is consistent on windows and on ubuntu.
Thank you very much indeed!
Thank you for your suggestions of optimization. Eh, the integer 8 does not really matter I believe, on modern hardware.
On windows and ubuntu, no matter integer 4 or 8, Intel fortran gives the same speed 0.5s.
gfortran on Ubuntu also gives about 0.6s no matter integer 4 or 8, which is decent enough.
It is an illustration code and optimization is not very important but thank you very much all the same, I highly appreciate it!
If you have multiple versions of Gfortran installed along with MinGW, Cygwin, WSL, etc., you have to be careful not to get the paths and environments mixed up. Here is how to check.
After building an EXE, run the Cygwin ldd utility on it. For the version compiled with Cygwin+Gfortran, I see:
T:\LANG\RChen>gfortran -O2 ran.f90 samplers.f90 EM_mix.f90 T:\LANG\RChen>ldd a.exe ntdll.dll => /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffabeee0000) KERNEL32.DLL => /cygdrive/c/WINDOWS/System32/KERNEL32.DLL (0x7ffabd8a0000) KERNELBASE.dll => /cygdrive/c/WINDOWS/System32/KERNELBASE.dll (0x7ffabc940000) cyggcc_s-seh-1.dll => /usr/bin/cyggcc_s-seh-1.dll (0x3f7530000) cygwin1.dll => /usr/bin/cygwin1.dll (0x180040000) cyggfortran-5.dll => /usr/bin/cyggfortran-5.dll (0x3f6e40000) cygquadmath-0.dll => /usr/bin/cygquadmath-0.dll (0x3f1d90000)
For the MinGW+Eq.Com.Gfortran built a.exe, ldd reports:
ntdll.dll => /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffabeee0000) KERNEL32.DLL => /cygdrive/c/WINDOWS/System32/KERNEL32.DLL (0x7ffabd8a0000) KERNELBASE.dll => /cygdrive/c/WINDOWS/System32/KERNELBASE.dll (0x7ffabc940000) msvcrt.dll => /cygdrive/c/WINDOWS/System32/msvcrt.dll (0x7ffabdf40000)
If, when you run ldd on what you think is a Cygwin built EXE, you see “msvcrt” in the output, that is a sign that your paths are mixed up.
Bite your tongue! Don’t blame Gfortran without checking! That was the whole point of my long post.
I just checked the Windows Julia 1.7.2 installation using ldd, and I find that many of Julia’s DLLs are built with MinGW, as well. This leads me to suspect is that if you compare Julia run times on Windows and Linux the Windows versions will come out as significantly slower. MinGW makes it convenient to port Linux applications to Windows, but there appears to be a price to pay.
Just as with Gfortran, it would be unfair to compare Ifort and Julia on Windows and conclude that Julia is slow compared to Fortran, without taking into account the reliance of Julia on MinGW.
Similarly, it would not be quite proper to compare the performance of a Linux application/package such as Julia to a MinGW Windows port of the same package and conclude that “Windows is three times slower than Linux.”
Thank you again @mecej4 ! Nice.
I think we are getting closer to fix the problem.
Now here is the thing. I installed cygwin64 from
Install Cygwin by running setup-x86_64.exe
as the website suggests.
As you can see from my desktop, there is a cygwin64 terminal icon there, I double clicked that icon, it seems I should be in cygwin64 terminal enviroment, however, as you said ( again, thank you very much indeed for the ldd trick, that is indeed helpful! ), perhaps my path is mixed up, because I do see my cygwin64 did not generate the one as you show, I have msvcrt as below,
- Do you know how to fix the environment variables?
My path variables are ,
Are you suggesting deleting the path of all other gfortran versions? Such as like gcc/bin/, etc?
- By the way, sorry if it is stupid question, is there a way to call the gfortran and Make in cygwin without using the cygwin64 terminal?
I briefly checked the folders of cygwin64, but I did not find things like gfortran.exe or make.exe.
In cygwin64 terminal, the ‘’‘clean’’’ part in make should be the same as if it is in pure linux,
clean: rm -f $(EXEC) *\.mod *\.mod0 *\.smod *\.smod0 *\.log *\.o *~
clean: @del /q /f $(EXEC) *.mod *.obj *~ > nul 2> nul
works for the Make in equation.com’s gcc pack for windows.
Yes, I see the problem in your screenshot that shows %PATH%. It includes the following line:
You do not have to use the Cygwin Terminal; I rarely use it. You can use Cygwin tools from any CMD or other command shell, if you make the Cygwin /bin and /usr/bin directories accessible through PATH. Regardless of how you go about this, it is ultimately your responsibility to arrange the environment to work correctly for the task that you are currently performing.
If you need more help with Windows %PATH% and other environment settings, you can consult web pages or manuals, or a local expert.