Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Why are SINGLE variables faster than INTEGER variables ?
#11
Quote:Apparently not always, as per the times posted above yours.  SINGLE is faster without integer division, which really blows my mind!  I really wonder what type of machine/architecture gives such results. 
Indeed, amazing. I wouldn't have thought so. - I googled it: Single-point division is faster than integer division
Quote:Yes, floating-point division can be faster than integer division under certain circumstances, especially if the processor has an efficient floating-point unit (FPU) and the hardware support for floating-point operations is optimized. However, this depends heavily on the specific hardware, the compiler used, and the exact data.

. . .

In summary:
While integer division can be faster in some cases, especially when high precision is not required or when the result needs to be rounded to an integer, floating-point division is often faster when the processor has a well-optimized FPU and the compiler adjusts the code accordingly. The actual speed depends on many factors and can therefore vary.
Reply
#12
Here are my laptop specs :  cpu AMD Ryzen 5 4500U / 16,0 Gb ram / Win11pro64
Reply
#13
(06-27-2025, 01:45 PM)SMcNeill Wrote: Integer Division (the \ division) is much faster than taking the integer value of normal division, as shown above.

x \ y is faster than INT(x / y).   At least, it always has been for me on Windows with the math processors on my PCs and Laptops.  Perhaps Linux or Mac handles them differently somehow?

No kidding? 

This is very very useful to know for any QB64 / QB64PE programmer, thanks for sharing.

Do we by chance have a FAQ anywhere with these little bits of wisdom collected together?

(06-27-2025, 04:21 PM)Kernelpanic Wrote: Yes, floating-point division can be faster than integer division under certain circumstances, especially if the processor has an efficient floating-point unit (FPU) and the hardware support for floating-point operations is optimized. However, this depends heavily on the specific hardware, the compiler used, and the exact data.
. . .
In summary:
While integer division can be faster in some cases, especially when high precision is not required or when the result needs to be rounded to an integer, floating-point division is often faster when the processor has a well-optimized FPU and the compiler adjusts the code accordingly. The actual speed depends on many factors and can therefore vary.

Hmm... I wonder if there is a way to check the hardware from code, so your program can choose the faster method at runtime, depending on the FPU type detected?
Reply
#14
(06-27-2025, 05:44 PM)madscijr Wrote:
(06-27-2025, 01:45 PM)SMcNeill Wrote: Integer Division (the \ division) is much faster than taking the integer value of normal division, as shown above.

x \ y is faster than INT(x / y).   At least, it always has been for me on Windows with the math processors on my PCs and Laptops.  Perhaps Linux or Mac handles them differently somehow?

No kidding? 

This is very very useful to know for any QB64 / QB64PE programmer, thanks for sharing.

Do we by chance have a FAQ anywhere with these little bits of wisdom collected together?

(06-27-2025, 04:21 PM)Kernelpanic Wrote: Yes, floating-point division can be faster than integer division under certain circumstances, especially if the processor has an efficient floating-point unit (FPU) and the hardware support for floating-point operations is optimized. However, this depends heavily on the specific hardware, the compiler used, and the exact data.
. . .
In summary:
While integer division can be faster in some cases, especially when high precision is not required or when the result needs to be rounded to an integer, floating-point division is often faster when the processor has a well-optimized FPU and the compiler adjusts the code accordingly. The actual speed depends on many factors and can therefore vary.

Hmm... I wonder if there is a way to check the hardware from code, so your program can choose the faster method at runtime, depending on the FPU type detected?

     Also when using Integer's the NATIVE REGISTER SIZE is going to be fastest.   On modern systems that _INTEGER64 !! Not Integer or Even Long. !!!

   Honestly.   Unless your doing something really, really performance critical then IMHO it really doesn't matter a lot I usually use DOUBLE as It doesn't very often overflow. !!.        The only time I use _byte, integer or long is when I'm doing file parsing then the file format selects the required data type !!!
Reply
#15
(06-27-2025, 08:43 AM)Elzaimer Wrote: ..... So, for me, I had to use INTEGER (only 2 bytes, so fast in my mind).....
That is a very common, but very wrong, misunderstanding/mistake.
As already explained by others, the 'standard' rule is: choose the type which is the same as the native register/type size of your CPU.

For 32 bit CPUs that would be anything with 32 bit = LONG (and not INTEGER like it has been used in a gazzilion programs)
For 64 bit CPUs that would be anything with 64 bit = _INTEGER64 in case of QB64.

HOWEVER... As you can read in all the posts, it HIGHLY depends on other things too:
- your specific CPU and its capabilities
but also:
- WHAT you want to calculate,
- HOW you're going to calculate,
- is it optimizable by compiler,
- is it optimizable by CPU during processing (branch prediction, pipelining),
- does your CPU has co-processor, FPU, special optimizations, ...


(06-27-2025, 05:44 PM)madscijr Wrote:
(06-27-2025, 01:45 PM)SMcNeill Wrote: Integer Division (the \ division) is much faster than taking the integer value of normal division.......
No kidding?  This is very very useful to know for any QB64 / QB64PE programmer, thanks for sharing.
Do we by chance have a FAQ anywhere with these little bits of wisdom collected together?
To be honest, this is explained literally in almost ANY (good) basic programming course/manual/etc.
(but it is true that it is often overlooked)


(06-27-2025, 05:44 PM)madscijr Wrote: Hmm... I wonder if there is a way to check the hardware from code, so your program can choose the faster method at runtime, depending on the FPU type detected?
AFAIK, no there is not. And even if there was, it would HIGHLY depend on WHAT you want to calculate and HOW you do it.
Because it also depends on how the compiler behaves and if it can optimize the code or not.
This includes dependency on how good your processor is with pipelining (is kind of like parallel processing) and branch predicting (which can vary very very wildly depending on processor).

Eg: you can use the theoretical 'faster' TYPE, but code a bad/slow routine for optimization. And thus it would be outperformed by using a theoretical 'slower' TYPE but coded in such way that it is optimized by the compiler and/or CPU.

So, I think the best way to do something like that, is writing a small 'test-routine' for each and every TYPE you'd wanna test, and check its timings at the beginning of your program. Then, depending on that timing, you run the proper dedicated routines with the appropiate types.

BUT, this also implies that you can NOT use pre-compiler statements to include/exclude routines; because you need to include ALL the different routines in your code since it highly depends on compiler AND cpu behavior. Removing them with conditional (pre-)compiling would defeat the whole purpose.

Also, in this case, one size does not fit all! That is: your test routines need to mimic the actual big calculation you wanna do in the main program. Otherwise, it would also defeat the purpose of the tests.
(eg: I could test all TYPES with integer division by powers of two, and in the main program I do non-power of two divisions, multiplications and what not..... The compiler and/or cpu would greatly optimize the test routines (because of 'powers of two'), but can't optimize the main program. So all test timings would be very off)


(06-28-2025, 12:13 AM)ahenry3068 Wrote: Also when using Integer's the NATIVE REGISTER SIZE is going to be fastest.   On modern systems that _INTEGER64 !! Not Integer or Even Long. !!!
Yes, this!!!11!!

And for as long as I know, this has always been the case!
And for as long as I know, people have always been 'confused' by that. lol
I can't count the amount of code I've seen where people declare their variables as 'INTEGER', thinking it would be faster/fasted, while in fact it has been the 'LONG' type since like almost forever (on 32-bit machines)....
Changing INTEGER to LONG is almost without exception the number one thing I always did when reviewing code (also fixed quite a lot of possible overflow problems).






As for floating point divisions:

Yep, it all depends on your (integrated or external) FPU.
It used to be that FPUs were rare and even if they existed, they were slow.

But, this has been changed since decades.
So, to know what is faster all depends on WHAT and HOW you calculate stuff.

For example, if you divide by powers of two, do NOT use integer division either! Instead use 'shift' operator, if the language supports it. And/or use a decent compiler which will recognize divisions by a power of two as a 'shift'. But luckily, as it happens today, almost all common compilers these days do recognize such calculations and convert them to shifts 'under the hood'.

As for integer divisions:

Guys, do NOT call or confuse INT(x/y) as an "integer division". It is absolutely not! It is a floating point division (where the result is casted to an integer). That is very different than a real integer division using the integer division operator: '\' (notice this is backslash, not a forward slash!).






PS: Another interesting dependency in all of this speed-testing and comparing bussiness:
Microsoft Windows + all bad behaving programs (like Chrome!).

In very short: your computer has a special timer, which is used to initiate interrupts.
The frequency of this timer can be set by any program (or Windows itself) and is often done so.
However, it is quite often set to a too high frequency and more than often not set back.
As such interrupts will be firing far more than needed and your CPU is increasingly busy.
This WILL and DOES slow down your computer, and in some cases significantly (up to 5% in some cases).
More about that here.

Point is: even on the same system, you can have very different results in speed tests. Great care should be taken when speed testing on modern systems... actually, far more than on older systems.
Who remembers QB30, GWBASIC, C64, ZX80?
Reply
#16
(06-28-2025, 12:13 AM)ahenry3068 Wrote: Also when using Integer's the NATIVE REGISTER SIZE is going to be fastest.

i think the cpu is garbage.  if it cannot do calculations involving smaller integers than its general purpose register size.  faster than floating point.  if the cpu is 64-bit.  which is way faster than intel 486dx for example.

it could be understood with 16-bit.  especially how intel tried to get more profits.  by just leaving out fpu.  or doing other stupid things before it invented celeron.  and going even further such as denormalizing problems we still have to deal with now on "x86" architecture.

we're not going to have 128-bit in the near future.  imagine having to shuffle 16 bytes at a time?  but the programmer needs only two bytes at a time?  if that's slower than figuring out a transcedental number to 100 digits.  then it simply means poor design.  sadly poor design has become price leader in many cases.  on computers being considered e-waste after.  ummm, five years after manufacture.  and even less time in the future.

so much for "register int" overused in a lot of legacy c code.  it won't be necessary any longer.  if declaring something as "long double" is faster instead.

this is just my opinion.
Reply
#17
Nobody has really given you a straight answer  Tongue The reason SINGLE can be faster is because "/" division is always floating point. When you use it with integer types they first get converted to SINGLE and then those get divided the same as regular SINGLEs, so making them integers just adds an extra step.

I'd also say separately the advice of "native integer size" is less relevant for modern processors, x86 can handle all the sizes just fine. The issue is a bigger deal for less powerful processors with more limited instruction sets, no cache, etc.
Reply
#18
(07-05-2025, 07:57 PM)hsiangch_ong Wrote:
(06-28-2025, 12:13 AM)ahenry3068 Wrote: Also when using Integer's the NATIVE REGISTER SIZE is going to be fastest.
i think the cpu is garbage.  if it cannot do calculations involving smaller integers than its general purpose register size.  faster than floating point.  if the cpu is 64-bit.  which is way faster than intel 486dx for example.

[snipped]
I highly suggest to read up on how processors and native code/assembler actually works, because it has nothing to do with poor design AT ALL, and even less with Intel being d$cks sometimes or dropping the ball.
Who remembers QB30, GWBASIC, C64, ZX80?
Reply
#19
(07-05-2025, 09:06 PM)DSMan195276 Wrote: Nobody has really given you a straight answer  Tongue The reason SINGLE can be faster is because "/" division is always floating point. When you use it with integer types they first get converted to SINGLE and then those get divided the same as regular SINGLEs, so making them integers just adds an extra step.

I'd also say separately the advice of "native integer size" is less relevant for modern processors, x86 can handle all the sizes just fine. The issue is a bigger deal for less powerful processors with more limited instruction sets, no cache, etc.
    
    I'll confess that I didn't actually realize the implicit conversion with the division operator (I should have).  

    The NATIVE REGISTER SIZE may be LESS relevant but it still is the best approach if you need absolutely the fastest code.    I won't even pretend to understand or explain all the in's and out's but I've run plenty of stress test bench marks that lean to that still being true.    

    It is true that Modern processors are really so fast that unless your doing something really cpu intensive you'll probably never notice the difference in using an Integer a Long or an _integer64   or for that matter one of the float types.     BASIC quite sensibly (as a beginners language) makes float (single) the default type because for the most part when a programmer types a formula in it mostly JUST WORKS.       Working code is ALWAYS more desirable than BROKEN FAST CODE...
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  _NEWIMAGE can't accept variables as dimensions? bobalooie 23 910 02-18-2026, 11:16 PM
Last Post: Unseen Machine
  generating a random number in the full range of that number? (Integer, Long) madscijr 2 641 05-01-2025, 09:11 PM
Last Post: madscijr
  testing a number's quare root is an integer and casting to a value? madscijr 22 3,374 01-29-2025, 11:12 PM
Last Post: Pete
  Determine a value is INTEGER TerryRitchie 17 3,258 07-27-2024, 05:03 PM
Last Post: Kernelpanic
  Is there a faster way to do this glow circle effect? Dav 11 2,067 06-16-2024, 11:51 PM
Last Post: Dav

Forum Jump:


Users browsing this thread: 1 Guest(s)