To be very clear, to me, this is absolutely nothing more than just a matter of building the compiler completely normally. It takes like two minutes all-in. I don't really get why the person who uploads the 32-bit Windows builds currently doesn't just also upload 64-bit ones. They could even just use the native 64-bit builds Lazarus already includes. Anyways, yeah. I'd like to actually make this happen, next time around.
Mailing lists / fpc-devel / 2021-12
I've asked this before, but perhaps I wasn't specific enough that time: what do I *personally*, specifically need to do to ensure that a native Windows 64-bit build winds up on the FPC website for the next release?
60 messages · 15 people · –
- BBen Grasset 19
- NNikolay Nikolov 10
- SSven Barth 6
- FFlorian Klämpfl 4
- MMartin Frb 4
- TTomas Hajny 3
- +9 more
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
Ben Grasset via fpc-devel schrieb am So.,
19. Dez. 2021, 08:33:
Show quoted text 7 lines
There is already a combined 32-/64-bit download available since 3.2.2. We *won't* provide a pure, native 64-bit download for Win64, because the x86_64-win64 is not suitable for other x86_64 targets or for compiling a i386 or i8064 cross compiler due to the missing Extended support. Until FPC provides the necessary code to emulate 80-bit floating point we simply avoid this potential headache by not providing it. As this has been discussed ad nauseam already, this decision is not up for discussion.
Regards,
Sven
Show quoted text 6 lines
And the main obstacle for 80 bit softfloat support are the library routines (log, exp etc.).
Show quoted text 7 lines
Hi!
19.12.2021 12:33, Florian Klämpfl via fpc-devel:
And the main obstacle for 80 bit softfloat support are the library routines (log, exp etc.).
Just out of curiosity, couldn't bochs' x87 fpu implementation be of some use here?
It is approx 12k of C code and it is LGPL. Supposedly it is not fast but conformant.
Or does it need to be (re-)implemented in Pascal itself? (Not implying it would be easy anyway, but still)
Regards,
Nikolai
Nikolai Zhubr wrote 6 lines
Note that FPC needs LGPL + static linking exception (the softfloat units are in the RTL).
Jonas
Show quoted text 9 lines
Nikolai might be right, looking at it’s license it seems usable:
https://github.com/lubomyr/bochs/blob/master/cpu/fpu/fsincos.cc
Same as the softfloat code we use it seems.
To throw my hat into the ring, I'd be willing to help out with developing some library routines. I did experiment once with using a truncated and factorised MacLaurin series to calculate Double-precision sin and cos simultaneously in native SSE2 (with sin and cos filling two elements of the same register), mainly so one wouldn't be forced to use the floating-point stack on 64-bit (the speed was about the same). For 128-bit though, I imagine it would have to be fully emulated, down to how the mantissa and exponent are interpreted. I admit I haven't studied the sfpu128 unit yet. If you need "log" and "exp" implmented in software, if you can give me the exact requirements and specifications, I'll see what I can do.
Gareth aka. Kit
Florian Klämpfl wrote 18 lines
Hi!
19.12.2021 19:28, J. Gareth Moreton via fpc-devel:
Show quoted text 11 lines
Well x87 does include log and exp (kind of), so bochs does too. It is known to successfully run lots of ancient 86/87 software, so I'd suppose this x87 emulation should be pretty much stable.
Apparently, x87 implementation in bochs is not tied to any sort of host-side floating-point capabilities, so it is portable. IIRC some people reported they used it on ARM.
Regards,
Nikolai
Gareth aka. Kit
Ben Grasset via fpc-devel schrieb am So., 19. Dez. 2021, 08:33: There is already a…
On Sun, Dec 19, 2021 at 3:46 AM Sven Barth via fpc-devel <
Show quoted text 28 lines
Explicitly *not *wanting to provide a native x86_64 bit build was not ever mentioned by anyone previously in any discussion I was involved in actually. Quite the opposite IIRC. I also fail to see how that makes any sense, personally. It just means continuing to tell everyone who wants native Win64 (which is very many people) "either download Lazarus or use FPCUpDeluxe".
If it's actually now somehow the case that an offer to provide Win64 builds would be refused though, I guess maybe I'll look into hosting them myself somewhere else? Although again I don't get why it would be fine for Linux to have a zillion archives for different configurations here: https://sourceforge.net/projects/freepascal/files/Linux/3.2.2/
but in some way bad to add one more to the windows files directory on the Sourceforge page.
AM Ben Grasset wrote 38 lines
Ben Grasset wrote 5 lines
As said, Windows 64-bit is a special case because it doesn't support/recommend extended. This makes cross compiling to targets that do difficult till we have softfloat support.
Marco van de Voort wrote 12 lines
Ok, let me throw in my 2 cents here....
Before I start:
- I have my own builds (so I do not depend on the outcome if this discussion)
- I am the one building the before-mentioned 64bit builds included in the Laz installer.
==> There may be some misunderstanding/oversight about those builds (see 2nd section of this mail)
- I have *not* downloaded the FPC from the link in the "Windows 64 bit section" (or quoting Sven: "combined 32-/64-bit download") https://www.freepascal.org/down/x86_64/win64.html ===> https://sourceforge.net/projects/freepascal/files/Win32/3.2.2/ I have no idea, what bitness the provided ppcx64.exe has. (i.e., the non-cross-compile ppc).
-----------------------
Afaik (ignoring any effort for extra builds required):
- The problem is *NOT* a native 64 bit "fpc.exe" ? => this only calls a ppc*.exe
- The problem is *NOT* a native 64 bit "ppcx64.exe" ? => 64 bit compiled targets don't require "extended" from the ppc, as they themself wont have support for it?
So up to this point, afaik there would be no problem, having those executables as 64-bit exe?
-----------------------
So the problem is about cross-compiling. Because such a cross compiler, needs to support "extended".
And here is what no-one has ever mentioned, when they refer to the "64bit fpc" included in Lazarus.
The cross compiler for compiling a "32bit exe" on a "64bit-development-system":
=> lazarus-2.2.0- fpc-3.2.2-cross-i386-win32 -win64.exe < == *** This contains a 32-bit "ppc386.exe" compiler ***
The "ppc386.exe" can do "extended", because it is a 32 bit exe. Even though it is part of a 64bit download, and indented to run on a 64bit system.
About the name "ppc386.exe" versus "ppccross386.exe": For some reason this is the name that "fpc.exe" is looking for, when called with "-Twin32 -Pi386". (At least it works in Lazarus)
-----------------------
Sven Barth wrote 5 lines
The downloads provided by Lazarus are also NOT a "pure, native 64-bit download". Only the "fpc.exe" and the non-cross "ppc64.exe" are native 64 bit.
As I said, I do not know, what is currently provided by the Fpc "combined 32-/64-bit download".
No Idea, if any of the fpc/ppc executable in this download are already 64-bit.
Martin Frb wrote 15 lines
.
.
- The problem is *NOT* a native 64 bit "ppcx64.exe" ? => 64 bit compiled targets don't require "extended" from the ppc, as they themself wont have support for it?
Wrong - applies only to the Win64 target, whereas e.g. 64-bit Linux (supported by the same compiler targetting 64-bit code) supports extended. This means that compiling source code with this compiler may result in a different binary as soon as there's e.g. an extended contstant included in the source code, or any compile-time calculations in this precision need to be performed.
So up to this point, afaik there would be no problem, having those executables as 64-bit exe?
.
.
There would, see above.
Tomas
Ok, let me throw in my 2 cents here.... Before I start: - I have my own builds (so I do…
PM Martin Frb wroteAs I said, I do not know, what is currently provided by the Fpc "combined 32-/64-bit download". No Idea, if any of the fpc/ppc executable in this download are already 64-bit.
It provides 32-bit fpc (so it builds for 32-bit windows by default) and the win32->win64 crosscompiler in a single installer. In Lazarus that means that you can target Win32 (default) and Win64 without any problem.
Previously you had to install the win32->win64 crosscompiler as a separate download.
So, presonally I really welcome this "combined" installer.
. . Wrong - applies only to the Win64 target, whereas e.g. 64-bit Linux (supported by the…
Tomas Hajny wrote 11 lines
Ok, I was too unspecific, I indeed just meant a 64-bit Window ppcx64.exe to compile a 64 bit target Windows app.
But indeed, I did not think about compile-time evaluations. Those will indeed differ.
Leaving the question if it is in that case actually desired that they are done in "extended" precision.
Imagine some code (targeted at Win-64) that uses "extended" (which will at runtime become "double"? Or at least be less precise than "extended").
Now if that code, does some calculations with those values, and the code is written so the calculations happen at runtime => then the calculations are done at lower precision.
This would potentially affect the result. I guess that would be expected behaviour.
But, if any change to the code (not even necessarily a functional change) would allow the compiler to do those calculations at compile time, then the value changes. And the entire behaviour of the app may change.
Possible, this could even be a change just in optimization settings (or upgrading FPC), allowing the compiler to to propagate constants...
So does that mean, any code (that is to be compiled for Win-64bit) is considered "unstable" if it contains "extended" ?
Of course if the above conclusions are correct, the choice for such code is
- sometimes (depending on various hard to predict factors) differ from 32 bit version
i.e. compiling to 64 bit: ending up, at different times, with either one of two (or more) different behaviours
- always differ from the 32bit version
i.e. compiling to 64 bit: ending up, with one and only one behaviours (although diff from 32 bit)
Martin Frb wrote 40 lines
Not necessarily - when targetting Win64, the user needs to be prepared for the lower precision. However, imagine that that the user compiles his source code for target x86_64-linux. The resulting binary and its output will be exactly the same if the source code is compiled (with the same options, etc.) on Linux or if it is compiled on Windows using a Win32 hosted compiler, but it will differ if using a Win64 hosted compiler. From compiler support point of view, this is an issue.
Tomas
Tomas Hajny wrote 20 lines
Ok. So a question of priority. (E.g., reducing maintenance on tests?)
Not to say, that due to ABI different registers may be used. Triggering different subsequent optimizations.....
And yes, I can see your point. That exact problem, that a bug in the optimizer manifested on windows, but not linux has cost me several weeks. (Because I could not get it with valgrind). So, I do get, that trying to minimize such things, is very appealing.
-----------------
> when targetting Win64, the user needs to be prepared for the lower
precision
Yes, but It is one thing to be prepared for:
- One (exactly one) "lower precision", and all behaviour (on that platform [1]) to be always according to that specific precision.
[1] on that platform, with that exact revision of the compiler. But with any compile options, and independent of none functional changes to the users code.
It is another thing to be prepared for
- A random[2] "precision" that will change depending on compiler options and/or seemingly unrelated changes in the user's code
[2] From the users view "random", in that the user can not predict all the factors that will affect the selection.
Currently the user must be prepared for the latter.
Because if for example anything changes that affects constant propagation, calculation may move from run to compile time, or vice versa. And with that the used "precision" for an individual calculation will change.
The user may not be able to predict under which conditions that happens. So for the user there are random changes to the behaviour of his program.
And this is not comparing the behaviour between the Linux and Windows exe (both 64 bit). I agree that different behaviour must be expected. This is the behaviour between compiling the same code, with the same compiler, several times for the same target win-64. Changing a compiler option, will/can change the behaviour of the resulting exe.
Such "optimization" depend changes normally happen, if
- the code has (hidden) bugs
- the code uses undocumented behaviour
But I believe "extended" is documented.....
-----
Just to say, I am not saying it has to be changed. Really does not matter to me.
Just trying to fully understand the matter, the possible side effects (of either path that can be taken), and so on.
Martin Frb via fpc-devel schrieb am Mi.,
12. Jan. 2022, 18:06:
Show quoted text 24 lines
No, it's a question of unnecessary support we want. We already had users that complained that their code compiled from Win64 to x86_64-linux behaved differently than if compiled from Win32 or from x86_64-linux. We don't want to promote (and support) a compiler that doesn't produce the same code as the other two variants.
Show quoted text 20 lines
No, it is deterministic, it's simply different from a native x86_64-linux compilation or one from Win32 as mentioned above and that is bad.
Regards,
Sven
Sven Barth wrote 13 lines
You completely missed the point.
I was NOT comparing Win vs Linux
I wrote
And this is not comparing the behaviour between the Linux and Windows exe (both 64 bit). I agree that different behaviour must be expected. This is the behaviour between compiling the same code, with the same compiler, several times for the same target win-64.
Note the 2nd line.
- The exact same pascal code
- The exact same 32-bit ppcx64.exe
- the exact same target: Only compiling to 64-bit Windows exe
Changing only compiler options (e.g. optimizations), could possible trigger a behavioural change in the resulting exe. Because some calculation changed between being compiled to run-time or compile-time.
=> ok, I have not deep enough insight into the optimizer, maybe constant-propagation is 100% independent of any option passed to the compiler.
Maybe constant-propagation will be the same at a levels of optimization....
But, also none functional changes such as
const c = extended(1.234567997807)
var a, b: extended;
begin
a := c;
...
b := c + a;
changed to
b:= c+c;This is still the same code. There is no reason for a user to assume the result should change.
But, depending on the code in between, I have seen cases were "c+a" was done run-time.
While "c+c" should be compile time.
So, maybe it's not byte by byte the same pascal code. But from a functional point of view, it is the same code.
Martin Frb wrote 34 lines
No, at least not in the general case if the optimizations are bug free. The only optimizations that might lead to behavior difference with the above mentioned points are those of -O4 (cause those might make use of undefined behavior) or $FASTMATH and both are true for any platform.
Show quoted text 26 lines
When compiling from a target supporting Extended to one only supporting Double there isn't a loss of precision when calculating values at compile time. The other way around however, there *is* and that is the more crucial problem.
Regards,
Sven
Show quoted text 5 lines
I'm curious, do other cross compilers like gcc
have similar problems? How do they solve it?
Mattias
Mattias Gaertner wrote 11 lines
Does C have an extended type ? I thought they had only single and double ?
Michael.
Ok, let me throw in my 2 cents here.... Before I start: - I have my own builds (so I do…
On Wed, Jan 12, 2022 at 7:38 AM Martin Frb via fpc-devel <
Show quoted text 12 lines
Every single executable that actually originates from the FPC toolchain (so like `fpc.exe`, `ppcx64.exe`, `ppudump.exe`, `pas2js.exe`, `h2pas.exe`, and so on) contained in the current "lazarus-2.2.0-fpc-3.2.2-win64.exe" installer that the Lazarus website directs to when you click "Download Now" on a system running 64-bit Windows *IS* currently 64-bit. I just verified this myself. That particular installer does not include any cross compilers at all, also (the ones to target 32-bit Windows from 64-bit come in the smaller "lazarus-2.2.0-fpc-3.2.2-cross-i386-win32-win64.exe" installer.
On Wed, Jan 12, 2022 at 7:55 AM Tomas Hajny via fpc-devel <
Show quoted text 8 lines
Isn't this specifically the kind of thing that the `FPC_SOFT_FPUX80` define solves? FPC does not even let you go from 64-bit Windows to 32-bit targets if that define isn't active IIRC, so presumably the same thing could be made the case in other scenarios if it's something people are widely concerned about.
In any case, people who want native 64-bit Windows toolchains want them pretty much exclusively for use *on *64-bit Windows to *target* 64-bit Windows, and will install any cross-compilers secondarily *if *they have a use for them. The 32-bit-to-64-bit Windows FPC toolchain is *not *a perfect drop-in replacement. Based on testing I did locally previously, it's not as fast as the native 64-bit one, and additionally there are other things to keep in mind like the 4GB RAM limit on 32-bit (which I have in fact seen more than one user on the Lazarus forums run into with larger projects, none of whom were using the 32-bit executables "on purpose").
On Wed, Jan 12, 2022 at 1:38 PM Martin Frb via fpc-devel It provides 32-bit fpc (so it…
On Wed, Jan 12, 2022 at 8:08 AM Bart via fpc-devel <
Show quoted text 7 lines
The archives that are actually provided *by* the Lazarus team solve that problem in an IMO more sensible way already, though. That is, rather than having to use strictly 32-bit executables even when running on and targeting 64-bit, you can just add the 32-bit optional cross binaries seen below to an otherwise entirely 64-bit installation:
[image: 32BitExecutables.png]
No, at least not in the general case if the optimizations are bug free. The only…
Sven Barth wrote 8 lines
/I understand only part of this issue. 64-bit windows doesn't have extended support, is there a reason for this? If it's simply processors, and it works on linux, why does it not work on windows?/
/Also, since it's 64-bit, wouldn't a double on a 64-bit system match or exceed the numeric range on an extended range for a 32-bit system?/
/I'm no expert on compiler numeric ranges, and 32/64 ranges aren't something I've studied a whole lot of, other than to note that 64-bit processors can handle *much* larger numbers, so I don't understand why this problem exists./
/Is there a summary of why this is a problem anywhere I can refer to so I can understand why this happens, and what (if anything) can be done to solve it?/
/I've always been fascinated by compilers, though I've never actually written anything except an assembler for dos several years ago, I was never able to extend that to other languages, because of lack of knowledge of how the cpu does things, but this is still an interesting topic for me, and I honestly can't figure out why there would be an issue at all./
/I'm not doubting there is one, I'm just missing a piece or two to understand it./
/Any help would be appreciated.
/
It does work on 64-bit Windows, it's just technically deprecated.
Beyond that, the 80-bit Extended type dates back to the mid 1980s, and ran on a particular part of the processor (the FPU, or Floating Point Unit), in such a way that it was able to provide a somewhat higher amount of precision than the 64-bit "Double" type that's most commonly used today. That said, the operations involved generally weren't / aren't nearly as efficient as the vector based SSE2+ ones used for 32-bit and 64-bit floats. So it fell out of favor for most use cases, outside of certain things like scientific code that actually needs the highest amount of precision possible even at the detriment of efficiency.
I'd personally argue that anyone writing code today that actually needs true 80-bit extended already certainly is likely to know what they're doing as far as tooling, thus meaning the majority of users are fairly unlikely to ever encounter any problems that directly relate to it.
On Wed, Jan 12, 2022 at 11:08 PM Travis Siegel via fpc-devel <
Show quoted text 44 lines
/I understand only part of this issue. 64-bit windows doesn't have extended support, is…
Travis Siegel wrote 40 lines
The i386 compiler uses the x87 FPU for floating point. The x87 supports the 32-bit single precision floating point type, the 64-bit double precision floating point type and the 80-bit extended precision extended floating point type. So, the best precision you get is 80-bit.
The x86_64 compiler uses SSE2 instructions for floating point. However, the SSE2 instructions only support 32-bit and 64-bit float types.
X86_64 processors still have the FPU, and it still functions in 64-bit mode, so the x86_64 compiler can still use the FPU for the 80-bit extended type. In fact, this is why the linux x86_64 compiler works without limitations. However, Windows doesn't guarantee future compatibility if the FPU is used.
Quote:
"The x87, MMX, and 3DNow! instruction sets are deprecated in 64-bit modes. The instructions sets are still present for backward compatibility for 32-bit mode; however, to avoid compatibility issues in the future, their use in current and future projects is discouraged."
A logical question that follows is how can they break it in future Windows versions, if it's supported by the CPU. The answer is, since Windows is a multitasking operating system, they might stop saving the FPU registers when switching between 64-bit tasks. So, the only guarantee that x87 FPU code will continue to work in future Windows versions is if it's in a 32-bit process.
It kinda sucks, but it is what it is. Microsoft have decided that the FPU is considered "legacy" and "deprecated". However, the replacement (SSE2) doesn't have all the capabilities that the FPU has, namely it doesn't have 80-bit extended precision. I guess, you can complain to Microsoft about that and not to Free Pascal developers, but I doubt that they will care. :)
Nikolay
It does work on 64-bit Windows, it's just technically deprecated. Beyond that, the 80-bit…
Ben Grasset wroteIt does work on 64-bit Windows, it's just technically deprecated. Beyond that, the 80-bit Extended type dates back to the mid 1980s,
The year 1980, not the mid 1980s. But the x86 family dates back to 1978. Most x86_64 instructions are the same as the ones, introduced in 1978, but with an added prefix to indicate they're 64-bit.
and ran on a particular part of the processor (the FPU, or Floating Point Unit),
Ran on an optional separate coprocessor chip, called Intel 8087. It was succeeded by 80187, 80287, 80387 and 80487. It was actually integrated into the CPU with the 486DX CPU, but the 486SX had no FPU (in fact, it was disabled). And the 487 was actually a 486DX in a different socket, that took full control of the system as soon as it was installed, while the 486SX on the motherboard was switched off.
The Pentium was the first CPU that always had the FPU integrated.
Show quoted text 7 lines
We do care about scientific code as well as fast code, that's why we support both the FPU and SSE2+ (as well as AVX, etc.).
Show quoted text 6 lines
Floating point precision bugs, caused by loss of precision are evil, because the code works most of the time during testing, but they can still cause intermittent faults, which can be catastrophic. Ariane 5 is a notable example.
Show quoted text 52 lines
On Wed, Jan 12, 2022 at 7:38 AM Martin Frb via fpc-devel < Every single executable that…
Ben Grasset wrote 50 lines
Really? Are you sure, because I just tested make cycle on Linux and the results are:
i386:
real 1m1.032s
user 0m53.194s
sys 0m5.572s
x86_64:
real 1m32.651s
user 1m21.486s
sys 0m9.414s
So, the 64-bit compiler is 50% slower. This is on an AMD Ryzen 9 5900X 12-core processor, 128 GB RAM and an SSD.
I haven't tested in Windows, but it would be very strange and suspicious if the results are very different. I would double check if that's really the case and also try some things, like disabling any antivirus programs that might be slowing down your computer by scanning every exe file, produced by the compiler.
and additionally there are other things to keep in mind like the 4GB RAM limit on 32-bit (which I have in fact seen more than one user on the Lazarus forums run into with larger projects, none of whom were using the 32-bit executables "on purpose").
A bug report with steps to reproduce would probably be nice.
Nikolay
On Wed, Jan 12, 2022 at 7:38 AM Martin Frb via fpc-devel < Every single executable that…
Ben Grasset wroteIsn't this specifically the kind of thing that the `FPC_SOFT_FPUX80` define solves?
It's indeed what it's intended to solve, but currently it still generates different values compared to an actual x87 fpu.
Jonas
Really? Are you sure, because I just tested make cycle on Linux and the results are: i386:
32bit on Windows 64-bit uses Wow64.. which has a bit of overhead as an emulation layer. I believe it's the same one they use for ARM64 too. I can only guess at how optimally it works performance-wise, but compiling a couple thousand-liner utils was annoying. You could (at least on the machine I was using at the time) watch it just sit there briefly before any compiler output happened.
Your test would probably have similar results, but the nuisance for me was the delay in the 32bit version actually starting. ________________________________
Earlier message 57 lines
The year 1980, not the mid 1980s. But the x86 family dates back to 1978. Most x86_64…
On Thu, Jan 13, 2022 at 1:25 AM Nikolay Nikolov via fpc-devel <
Show quoted text 5 lines
FPC *chooses *not to generate x87 FPU instructions on 64-bit Windows solely because "it's deprecated". There's no actual technical limitation in play for user-mode code as far as the OS support for it goes.
On Thu, Jan 13, 2022 at 1:25 AM Nikolay Nikolov via fpc-devel <
wrote:
Show quoted text 5 lines
I don't disagree with you, but you're missing my point, which is that there's trivial solutions for this other than mandating the use of an entirely 32-bit bit toolchain even for the common user who just wants to use a 64-bit toolchain to generate 64-bit applications on their own 64-bit operating system.
Simply dropping a 32-bit copy of ppc386.exe into the bin folder of an otherwise all-64-bit FPC installation is all that's needed be able to build the 32-bit RTL and packages, and then start building 32-bit programs, for example.
Really? Are you sure, because I just tested make cycle on Linux and the results are: i386:
On Thu, Jan 13, 2022 at 1:58 AM Nikolay Nikolov via fpc-devel <
Show quoted text 5 lines
It would be neither of those things. The exception handling on x64 Windows is the fastest provided by FPC, for example (though the compiler AFAIK avoids doing anything that would generate exception handling code within its own codebase as much as possible).
On Thu, Jan 13, 2022 at 1:58 AM Nikolay Nikolov via fpc-devel <
wrote: A bug report with steps to reproduce would probably be nice.
That limit is a fundamental hardware limitation, not a bug. Not at all hard to imagine someone encountering it on 32-bit particularly if they're using Lazbuild for multi-threaded compilation.
32bit on Windows 64-bit uses Wow64.. which has a bit of overhead as an emulation layer. I…
On Thu, Jan 13, 2022 at 3:28 AM Alexander Grotewohl via fpc-devel <
Show quoted text 5 lines
It should be kept in mind also that neither 32-bit or 64-bit FPC use GNU LD for linking on Windows by default, but rather FPC's internal one, and it's not hard to imagine why that might perform better on 64-bit as well.
Ben Grasset wrote 11 lines
My imagination fails here - why?
Tomas
The i386 compiler uses the x87 FPU for floating point. The x87 supports the 32-bit single…
Nikolay Nikolov wrote 41 lines
Thank you, a very well written explanation. Now it makes sense. I appreciate your time and effort explaning the issue.
I wasn't aware of the whole MS not supporting the FPU thing, that was the missing puzzle piece.
On Thu, Jan 13, 2022 at 1:58 AM Nikolay Nikolov via fpc-devel < It would be neither of…
Ben Grasset wrote 11 lines
So, instead of giving actual benchmark data on the Windows performance, you speculate by claiming that having faster exception handling matters, and then you immediately debunk your own argument by admitting it probably doesn't matter for the compilation speed. Sure, using SSE2 is also faster, but it doesn't matter for the compilation speed at all, because all the performance critical parts are integer code, therefore it would be silly to give this as an argument as well. Sometimes 64-bit is faster (due to SSE2, AVX, exception handling, having more registers), sometimes 32-bit is faster (pointers are half the size, leading to less memory use, leading to less memory bandwidth requirements and more data fitting in the processor caches). Which is faster must always be determined by running some sort of benchmark, not by theoretical speculation. Rule number 1 of optimization is "never assume".
The fact that 32-bit x86 is sometimes faster is the reason why things like x86-32
Show quoted text 7 lines
We claim it's virtually impossible to exceed it in practice and we don't support a native win64 compiler, therefore it's a bug, if it's impossible to compile something with the 32-bit crosscompiler.
Not at all hard to imagine someone encountering it on 32-bit particularly if they're using Lazbuild for multi-threaded compilation.
Imagining something is one thing, whether it's possible to occur in practice is another.
Why would it matter whether you use lazbuild with multi-threaded compilation? Doesn't lazbuild start separate compiler processes? Every 32-bit process gets a separate 4GB address space (meaning that each process has a different set of page tables, thus a different mapping of linear to physical memory addresses, this is a memory protection mechanism, that ensures that one process isn't able to destroy the memory of another process). In 64-bit operating systems (as well as 32-bit, that use PAE, that is Physical Address Extension), each such set of page tables can map 32-bit linear memory pages to physical memory beyond the 4GB limit (with PAE it's a 32-bit to 36-bit mapping, in long mode it's a 32-bit to 64-bit mapping), therefore running multiple 32-bit processes at the same time can access more than 4GB in total, even though each process is limited to 4GB.
Nikolay
On Thu, Jan 13, 2022 at 1:25 AM Nikolay Nikolov via fpc-devel < FPC *chooses *not to…
Ben Grasset wrote 10 lines
What do other win64 compilers do? Do they generate x87 FPU code for 64-bit Windows?
Show quoted text 24 lines
So, instead of giving actual benchmark data on the Windows performance, you speculate by…
Nikolay Nikolov wrote 30 lines
Ok, I did some testing in Windows 10 21H2 and the 32-bit crosscompiler was faster. I tested compiling lazarus for win64 from lazarus git, using FPC 3.2.2. The crosscompiler is the one that we ship, the native compiler is the one that is shipped with lazarus 2.2.0 for win64. I did not use multithreaded compilation, because "make -j24" didn't work with lazarus. Maybe the lazarus makefiles don't support that and I should use lazbuild, but I don't know how. I tested "make all", not "make bigide". Both the FPC 3.2.2 crosscompiler and the native compiler were on an SSD, on an NTFS filesystem, with NTFS compression enabled. The lazarus sources that I compiled were on a HDD (no space on my windows SSD partition, sorry), but I have 128GB RAM, most of which are free and used by Windows as cache. I did several runs and discarded the first result, to avoid the effect of HDD files not being in the cache. Before each run, I cleaned up with right click->TortoiseGit->Clean up...->Clean Type = "Remove all untracked files (-fx)"; + "Remove untracked directories (-d)". This was followed by emptying the recycle bin. I have the default Microsoft antivirus program Windows Defender installed and fully updated. I tested both with antivirus real-time protection enabled and disabled. All measurements were made using "Measure-Command" in PowerShell. Here are the best results for each case:
antivirus off:
ppcrossx64: 83.8517351 seconds
ppcx64: 85.0845576 seconds
with antivirus on there's a huge variance of speeds:
ppcrossx64: 90.3048706 seconds - 95.4332713 seconds
ppcx64: 86.8207751 seconds - 99.2315772 seconds.
There were some ppcx64 runs that were slightly faster with antivirus on, but there were also slower and they didn't converge to a single value after several runs, but retained their random variance. But with the antivirus off, the crosscompiler was clearly faster.
Any suggestions for testing multithreaded compilation of lazarus are welcome. I'll be happy to test that as well.
Nikolay
So, instead of giving actual benchmark data on the Windows performance, you speculate by…
On Thu, Jan 13, 2022 at 11:28 AM Nikolay Nikolov via fpc-devel <
Show quoted text 7 lines
I went ahead and tested "make cycle" for both ppcx64.exe and ppc386.exe, using PowerShell's "Measure Command" for timing as it's the most accurate method I'm aware of on Windows. Both results came in under one minute, and the 64-bit compiler *was *faster, though not by a large amount for that relatively short workload (I might test a full repo build later to see what the differences are like between longer compilations). This also would seem to show that what CPU you have basically stops mattering after a certain point as far as FPC's performance goes, as mine is MUCH slower than yours (i7-4790K currently).
64-bit:
PS D:\fpclaz\FPCSource\compiler> Measure-Command {Start-Process make -ArgumentList "cycle PP=D:\fpclaz\fpc\bin\x86_64-win64\ppcx64.exe" -Wait}
Days : 0
Hours : 0
Minutes : 0
Seconds : 52
Milliseconds : 815
Ticks : 528157597
TotalDays : 0.000611293515046296
TotalHours : 0.0146710443611111
TotalMinutes : 0.880262661666667
TotalSeconds : 52.8157597
TotalMilliseconds : 52815.7597
32-bit:
PS D:\fpclaz\fpcsource\compiler> Measure-Command {Start-Process make -ArgumentList "cycle PP=D:\fpclaz\fpc\bin\x86_64-win64\ppc386.exe" -Wait}
Days : 0
Hours : 0
Minutes : 0
Seconds : 56
Milliseconds : 873
Ticks : 568733659
TotalDays : 0.000658256549768519
TotalHours : 0.0157981571944444
TotalMinutes : 0.947889431666667
TotalSeconds : 56.8733659
TotalMilliseconds : 56873.3659
What do other win64 compilers do? Do they generate x87 FPU code for 64-bit Windows?
On Thu, Jan 13, 2022 at 9:48 AM Nikolay Nikolov via fpc-devel <
Show quoted text 5 lines
Yes. Given the following:
#include <stdio.h>long double do_three(long double x, long double y, long double z) {
return (((x * x) / y) + z);}
int main () {
printf("%d\n", sizeof(long double));
printf("%.19Lf\n", do_three(9.4567575785454772685L,2.1211991522332311497L, 16.1216453784376343456L)); }
GCC 11.2 produces this assembly with "gcc -O3 -march=native -S test.c" on 64-bit Windows 10:
do_three:
.seh_endprologue
fldt (%rdx)
fldt (%r8)
fldt (%r9)
fxch %st(2)
movq %rcx, %rax
fmul %st(0), %st
fdivp %st, %st(1)
faddp %st, %st(1)
fstpt (%rcx)
ret
.seh_endproc
and Clang 13.0 produces this with the same command line arguments passed:
do_three: # @do_three # %bb.0:
movq %rcx, %rax
fldt (%rdx)
fldt (%r8)
fldt (%r9)
fxch %st(2)
fmul %st, %st(0)
fdivp %st, %st(1)
faddp %st, %st(1)
fstpt (%rcx)
retq
Running the program prints this with both compilers:
16
58.2818846964779790909
So the answer to Mattias's question about C compilers from before is "they just directly support it on Windows".
On Thu, Jan 13, 2022 at 11:28 AM Nikolay Nikolov via fpc-devel < I went ahead and tested…
Ben Grasset wrote 53 lines
Just for the record, is this with antivirus off or on and which antivirus program?
Also, I know my first benchmark was make cycle comparison between ppc386 and ppcx64 under linux (and it showcased that 32-bit compilers can be much faster, when CPU is the bottleneck), but then I realized it can be an apples to oranges comparison, because ppc386 contains a very different code generator, it emits 32-bit code, instead of 64-bit code. That's why I tried compiling lazarus for win64 using ppcx64 and ppcrossx64. On my computer it turned out that ppcrossx64 was slightly faster, when antivirus is turned off. When antivirus is on, both became slower, with sometimes ppcrossx64 was slightly slower, but other times ppcx64 was still slower. It was less predictable with more random variance in performance, but it felt like ppcrossx64 was slightly slower on average with antivirus on. Another issue is that I/O turned out to be a huge bottleneck, even with enormous amounts of RAM for cache. For example, cleaning up the git repo between runs sends the deleted files to the recycle bin. I then emptied the recycle bin, before running the next build. However, skipping this recycle bin emptying resulted in a performance boost that was larger than the difference between ppcrossx64 and ppcx64. So far, my preliminary conclusions are:
1) CPU is usually not a huge bottleneck when compiling with FPC under Windows
2) I/O is a huge bottleneck, even with large amounts of free RAM available for cache
3) Windows Defender is also a huge bottleneck and it appears to hurt startup of 32-bit programs more (perhaps there are more win32 viruses to scan for in exe files?). But it still hurts both win32 and win64 programs. Turning it off during long compilations is almost always beneficial.
4) The compilation speed of ppcx64 and ppcrossx64 is comparable regardless of whether Windows Defender is on or off.
5) When CPU is the bottleneck (antivirus turned off), the 32-bit hosted compiler is faster. This still needs confirmation, though, because your results show 32-bit being slower, but you didn't say whether antivirus was off.
Nikolay
On Thu, Jan 13, 2022 at 10:18 PM Nikolay Nikolov via fpc-devel <
Show quoted text 5 lines
I have no anti-virus actively installed or enabled on an ongoing basis at all. I just occasionally do manual scans with Malwarebytes and such. Beyond that, Windows is installed on a SATA SSD (Samsung 860 Pro), and my RAM is 16GB DDR3-2400 CL10.
Thank you, a very well written explanation. Now it makes sense. I appreciate your time…
On Thu, Jan 13, 2022 at 9:20 AM Travis Siegel via fpc-devel <
Show quoted text 5 lines
It's not a realistic concern in actuality. There's a reason almost every other compiler just continues to generate x87 FPU instructions on x64 Windows when appropriate the same way they do for whatever other platforms are supported.
On Thu, Jan 13, 2022 at 10:18 PM Nikolay Nikolov via fpc-devel < I have no anti-virus…
Ben Grasset wrote 11 lines
For the record, I did try make cycle for ppc386 and ppcx64 on my Windows 10 (with Windows Defender turned on) and both finished in exactly 42 seconds :)
Nikolay
On Thu, Jan 13, 2022 at 11:38 PM Nikolay Nikolov via fpc-devel <
Show quoted text 6 lines
Not surprising that you closed the gap a bit with your 5900X IMO, although that's still a decent improvement over both of your Linux results. I do think probably linking with GNU LD isn't as fast in most cases as linking internally, as I mentioned before. Though using LLD or mold instead of LD might be a different story.
Ben Grasset wrote 12 lines
No, it's not, because in linux I tested "make -j24 all" in the compiler directory, which also builds all the packages, textmode ide and utilities (and also does a parallel build), but in Windows I tested only "make cycle", like you did.
Nikolay
On Thu, Jan 13, 2022 at 9:48 AM Nikolay Nikolov via fpc-devel < Yes. Given the following:…
Ben Grasset wrote 60 lines
For MSVC it's different:
=== code begin ===
; Function compile flags: /Ogtpy
; File C:\Users\Sven\source\repos\floattest\main.cpp ; COMDAT ?do_three@@
_TEXT SEGMENT
x$ = 8
y$ = 16
z$ = 24
?do_three@@ PROC ; do_three, COMDAT
; 4 : return (((x * x) / y) + z);00000 f2 0f 59 c0 mulsd xmm0, xmm0 00004 f2 0f 5e c1 divsd xmm0, xmm1 00008 f2 0f 58 c2 addsd xmm0, xmm2
; 5 : }
0000c c3 ret 0
?do_three@@ ENDP ; do_three _TEXT ENDS
=== code end ===
=== output begin ===
8
58.2818846964779808673
=== output end ===
(though to be fair it does the same on 32-bit as well)
Regards,
Sven
On Thu, Jan 13, 2022 at 9:20 AM Travis Siegel via fpc-devel < It's not a realistic…
Ben Grasset wrote 11 lines
Just FYI what Delphi writes in their documentation ( https://docwiki.embarcadero.com/RADStudio/Sydney/en/Simple_Types_(Delphi)#Real_Types ):
On i386 Windows Extended is 80-bit, on x86_64 Linux, i386 macOS and i386 iOS simulator it's 128-bit and on all other platforms (which includes x86_64 Windows) it's 64-bit.
So Delphi went the same way as we did.
Regards,
Sven
Show quoted text 10 lines
The 128-bit is only 80bit precision, right?
With ppcx64 on Linux I get sizeof(extended)=10.
Mattias
Mattias Gaertner via fpc-devel schrieb am
Fr., 14. Jan. 2022, 10:01:
Show quoted text 19 lines
I meant regarding Windows x86_64. We don't support 128-bit floating point ,
Sven
For MSVC it's different: === code begin === ; Function compile flags: /Ogtpy ; File…
On Fri, Jan 14, 2022 at 1:27 AM Sven Barth via fpc-devel <
wrote: (though to be fair it does the same on 32-bit as well)
Yeah, MSVC (for some reason) universally defines "long double" as exactly an alias for regular 64-bit double, whereas GCC and Clang (more correctly IMO) define it as an 80-bit type equivalent to FPC's traditional "extended". So even on 32-bit with MSVC you have to hand-write assembly to make use of x87 FPU instructions.
Just FYI what Delphi writes in their documentation (…
On Fri, Jan 14, 2022 at 1:33 AM Sven Barth via fpc-devel <
wrote: So Delphi went the same way as we did.
I'd say Delphi imitating MSVC is sort of to be expected though, whereas *usually
*FPC makes similar choices to GCC.
On Fri, Jan 14, 2022 at 1:27 AM Sven Barth via fpc-devel < Yeah, MSVC (for some reason)…
Ben Grasset wrote 11 lines
Did you test a windows gcc (win64 SEH) or a SJLJ "posix" (basically unported Unix) gcc ?
On Fri, Jan 14, 2022 at 10:46 AM Marco van de Voort via fpc-devel <
Show quoted text 5 lines
It was the SEH MinGW-w64 based GCC 11.2 that MSYS2 provides through their Windows version of pacman.
AM Ben Grasset wroteIt was the SEH MinGW-w64 based GCC 11.2 that MSYS2 provides through their Windows version of pacman.
Also, more accurately, I should have said before that the *precision *of "long double" is 80-bit and equivalent to FPC's "extended" with GCC and Clang on Windows x64. The data type storage size is actually larger though (128 bits).
No, it's not, because in linux I tested "make -j24 all" in the compiler directory, which…
On Fri, Jan 14, 2022 at 5:49 AM Nikolay Nikolov via fpc-devel <
Show quoted text 5 lines
That isn't what you said in your original comment about benchmarking on Linux. You specified "make cycle", which is what I was going off of.
Ben Grasset wrote 8 lines
Yes, my mistake, I wrote it in a hurry. Here's exactly what I tested in linux:
make -j `nproc` clean OS_TARGET=linux CPU_TARGET=i386 BINUTILSPREFIX= PP=/usr/bin/ppcx64
make -j `nproc` all OS_TARGET=linux CPU_TARGET=i386 BINUTILSPREFIX= PP=/usr/bin/ppcx64
versus:
make -j `nproc` clean OS_TARGET=linux CPU_TARGET=x86_64 PP=/usr/bin/ppcx64 make -j `nproc` all OS_TARGET=linux CPU_TARGET=x86_64 PP=/usr/bin/ppcx64
And this is all run entirely on my SSD (Samsung SSD 860 EVO 500GB), while on Windows, the code I compile is on my HDD (the SSD only contains Windows, FPC and Lazarus).
Btw, a full testsuite run in Linux on my computer is also much faster on i386, compared to x86_64. But now I'm also in a hurry, so I won't post any exact measurements.
Nikolay
Just for the record, is this with antivirus off or on and which antivirus program? Also,…
5) When CPU is the bottleneck (antivirus turned off), the 32-bit hosted compiler is faster. This still needs confirmation, though, because your results show 32-bit being slower, but you didn't say whether antivirus was off.
Compilation speed of FPC is typically memory bandwidth/cache limited. So due to using smaller data types it is obvious that the 32 bit compiler is faster.
Nikolai might be right, looking at it’s license it seems usable:…
Florian Klämpfl wrote 18 lines
I started a first translation and committed it to
https://gitlab.com/freepascal.org/fpc/source/-/tree/floatx80funcs
