Integer data types in 32-bit and 64-bit

New to FreeBASIC? Post your questions here.
fzabkar
Posts: 154
Joined: Sep 29, 2018 2:52
Location: Australia

Integer data types in 32-bit and 64-bit

Post by fzabkar »

ISTM that one should avoid using Integer data types if one wants to compile the same source for 32-bit and 64-bit targets. Is there a valid reason for ever using Integers?
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Integer data types in 32-bit and 64-bit

Post by jj2007 »

There is a lot of confusion caused by the usage of "integer" and "long". FB's types differ from the C types: in FB, an integer has 32 bits in 32-bit code, but 64 bits in 64-bit code. In contrast, a long has always 32 bits.

As a rule, if it's not a pointer, use long. You will rarely need a 64-bit for ... next counter, right?
badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Integer data types in 32-bit and 64-bit

Post by badidea »

You can even redefine the basic data types, and forget about (u)integer completely.
Example:

Code: Select all

'sick of typing integer
#define i8 byte
#define u8 ubyte
#define i16 short
#define u16 ushort
#define i32 long
#define u32 ulong
#define i64 longint
#define u64 ulongint
#define f32 single
#define f64 double

#define rnd_range(low, high)_
	(rnd(1) * (high - low) + low)

type layer_type
	dim as i32 num_cells
	dim as f32 cell(any)
	dim as f32 link(any, any) 'N input <-> M output
end type

type nn_type
	dim as i32 num_layers
	dim as layer_type layer(any)
	declare constructor(num_cells() as i32)
	declare destructor()
	declare sub show_summary()
	declare sub visualise(w as i32, h as i32)
end type

'build and initialise the neural network
constructor nn_type(num_cells() as i32)
	dim as i32 ub = ubound(num_cells)
	num_layers = ub + 1
	redim layer(0 to ub)
	for i as i32 = 0 to ub
		layer(i).num_cells = num_cells(i)
		redim (layer(i).cell)(num_cells(i)) 'crazy syntax, who needs pointers anyway?
		'fill cells with initial values
		for j as i32 = 0 to num_cells(i) - 1
			layer(i).cell(j) = rnd_range(-1, +1)
		next
		'allocate memory for the links
		if i <> ub then 'skip final layer, no further links
			redim (layer(i).link)(num_cells(i), num_cells(i + 1)) 'more crazy business!
			'fill links with initial values
			for j as i32 = 0 to num_cells(i) - 1
				for k as i32 = 0 to num_cells(i + 1) - 1
					layer(i).link(j, k) = rnd_range(-1, +1)
				next
			next
		end if
	next
	print "constructor nn_type() - done"
end constructor

'let do some clean-up
destructor nn_type()
	for i as i32 = 0 to ubound(layer)
		erase layer(i).link
		erase layer(i).cell
	next
	erase layer
	print "destructor nn_type() - done"
end destructor

sub nn_type.show_summary()
	print "num_layers: "; num_layers
	for i as i32 = 0 to num_layers - 1
		print "layer(" & i & ").num_cells: "; layer(i).num_cells
	next
end sub

'graphics screen needed, w = width, h = height
sub nn_type.visualise (w as i32, h as i32)
	dim as i32 cell_radius = 10
	dim as u32 cell_color = &hff00ff00 'green
	dim as u32 link_color = &hff0077ff 'blueish
	dim as i32 w_dist = w / num_layers
	for i as i32 = 0 to num_layers - 1
		dim as i32 num_cells = ubound(layer(i).cell)
		dim as i32 h_dist = h / num_cells
		for j as i32 = 0 to num_cells - 1
			circle (w_dist * (i + 0.5), h_dist * (j + 0.5)), cell_radius, cell_color
		next
		if i <> num_layers - 1 then 'skip last layer
			dim as i32 num_cells_next = ubound(layer(i + 1).cell)
			dim as i32 h_dist_next = h / num_cells_next
			for j as i32 = 0 to num_cells - 1
				for k as i32 = 0 to num_cells_next - 1
					line(w_dist * (i + 0.5), h_dist * (j + 0.5))-_
						(w_dist * (i + 1.5), h_dist_next * (k + 0.5)),_
						link_color
				next
			next
		end if
	next
end sub

const as i32 SW = 800, SH = 600
screenres SW, SH, 32
width SW \ 8, SH \ 16

'the size of the neural network is define by the user/caller
dim as i32 nn_size_def(...) = {2, 8, 5, 3}
dim as nn_type nn = nn_type(nn_size_def())
nn.show_summary()
nn.visualise(SW, SH)

getkey()
screen 0 'close graphics screen, for destructor printout
There maybe cases where using 32-bit integers on a 64-bit cpu is slower than using 64-bit integers. But I expect the difference to be very minimal.
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: Integer data types in 32-bit and 64-bit

Post by BasicCoder2 »

@badidea
Added your contribution to my useful stuff folder :)
Can that ANN be made to actually work?
example:
Set of 8x8 binary images (maybe ascii characters) as inputs to recognize over any binary noise the desired ascii code as output?
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Integer data types in 32-bit and 64-bit

Post by jj2007 »

badidea wrote:There maybe cases where using 32-bit integers on a 64-bit cpu is slower than using 64-bit integers.
Maybe.

Code: Select all

#Define elements 100000000
if (sizeof(any ptr))=8 Then
	Print "sizes in 64-bit code:"
else
	Print "sizes in 32-bit code:"
endif
Print sizeof(integer), "integer"
Print sizeof(long), "long"

Dim shared As long longvar(elements)
Dim shared As integer intvar(elements)
Dim As long tmp, ms
Dim As longint sumi, suml
Dim As double ti, tl
for n as integer=0 to elements-1	' create an array of random integers and longs
	tmp=Rnd()*16
	longvar(n)=tmp
	intvar(n)=tmp
next
ti=Timer()
for n as integer=0 to elements-1	' sum of integers
	sumi+=intvar(n)
next
ti=Timer()-ti
tl=Timer()
for n as integer=0 to elements-1	' sum of longs
	suml+=longvar(n)
next
tl=Timer()-tl
ms=1000*ti
Print "Sum integer=";sumi;" added in ";ms;" ms"
ms=1000*tl
Print "Sum long   =";suml;" added in ";ms;" ms"
sleep
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Integer data types in 32-bit and 64-bit

Post by dodicat »

Integer is still required for retrieved info from screeninfo , imageinfo , screencontrol in 64 bits.
But you will get an error message if you use long, so just change to integer for these things.
badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Integer data types in 32-bit and 64-bit

Post by badidea »

jj2007 wrote:Maybe...
My results:

fbc32 -gen gas test.bas

Code: Select all

sizes in 32-bit code:
 4            integer
 4            long
Sum integer= 800010752 added in  314 ms
Sum long   = 800010752 added in  314 ms
fbc32 -gen gcc test.bas

Code: Select all

sizes in 32-bit code:
 4            integer
 4            long
Sum integer= 800010752 added in  351 ms
Sum long   = 800010752 added in  342 ms
fbc64 -gen gcc test.bas

Code: Select all

sizes in 64-bit code:
 8            integer
 4            long
Sum integer= 800010752 added in  338 ms
Sum long   = 800010752 added in  342 ms
So indeed no significant difference. Note that this is mostly a memory heavy test, with CPU often waiting / idling / starving.
BasicCoder2 wrote:Can that ANN be made to actually work?
It is work in progress. I will open a new topic when done / more complete.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Integer data types in 32-bit and 64-bit

Post by jj2007 »

badidea wrote:So indeed no significant difference.
FreeBASIC Compiler - Version 1.07.1 (2019-09-27), built for win32 (32bit)

Code: Select all

sizes in 32-bit code:
 4            integer
 4            long
Sum integer= 400021326 added in  135 ms
Sum long   = 400021326 added in  135 ms
FreeBASIC Compiler - Version 1.07.1 (2019-09-27), built for win64 (64bit)

Code: Select all

sizes in 64-bit code:
 8            integer
 4            long
Sum integer= 400021326 added in  58 ms
Sum long   = 400021326 added in  30 ms
With 150 Million elements, FB64:

Code: Select all

Sum integer= 1199937252 added in  175 ms
Sum long   = 1199937252 added in  89 ms
I would call the difference significant.
badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Integer data types in 32-bit and 64-bit

Post by badidea »

Strange, I'll do some more tests on other systems and on Windows...
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Integer data types in 32-bit and 64-bit

Post by dodicat »

Looks like there is no way to use integer everywhere or long everywhere to satisfy 32 and 64 bits.
In 64 bits ulong is needed for 32 bit colours, so Uinteger is out.
In 64 bits integer is needed for screeninfo e.t.c. so long is out.
There seems to be a bug If I try to use long and cast to integer in (64 bits)

Code: Select all

screen 20
dim as long xres,yres

screeninfo *cast(integer ptr,@xres),*cast(integer ptr,@yres)
print xres,yres
sleep
 
for fun, from badidea's thing.

Code: Select all

screen 20
dim as integer xres,yres
screeninfo xres,yres
 #define map(a,b,x,c,d) ((d)-(c))*((x)-(a))\((b)-(a))+(c)
type pt
    as long x,y
end type

dim as long def(1 to 5) = {2,8,5,3,6}

dim as long sum
for n as long=lbound(def) to ubound(def)
    sum+=def(n)
next

dim as pt p(1 to sum)

#macro selector(x,a)
for z as long=2 to x+1
     var y=map(1,(x+2),z,0,yres)
     p(n)=type(a,y)
     n+=1
 next z
#endmacro

dim as long start=100
dim as long seperation=200
dim as long n=1
do
    for m as long=lbound(def) to ubound(def)
        selector(def(m),((m-1)*seperation+start))
    next m
loop until n>sum

for n as long=lbound(p) to ubound(p)
    circle(p(n).x,p(n).y),15,15
next n

for n1 as long =lbound(p) to ubound(p)-1
    for n2 as long =n1+1 to ubound(p)
        if abs(p(n1).x-p(n2).x)=seperation then line(p(n1).x,p(n1).y)-(p(n2).x,p(n2).y),map(0,xres,p(n1).x,1,14)
    next
next

sleep 
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Integer data types in 32-bit and 64-bit

Post by jj2007 »

dodicat wrote:In 64 bits integer is needed for screeninfo e.t.c. so long is out
I wonder if we really need 64 bits to calculate the screen resolution. With my current hardware, 16 bits are already generous for expressing my 1366 pixels of horizontal resolution ;-)
badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Integer data types in 32-bit and 64-bit

Post by badidea »

I did some more tests with a bit modified code:

Code: Select all

#Define elements 100000000 '100M

#ifdef __FB_WIN32__
	#define OS "Windows"
#else
	#ifdef __FB_LINUX__
		#define OS "Linux"
	#else
		#define OS "Unknown OS"
	#endif
#endif

#ifdef __FB_64BIT__
	#define BITS "64-bit"
#else
	#define BITS "32-bit"
#endif

print __FB_SIGNATURE__ & " " & BITS & " " & __FB_BACKEND__ & " on " & OS

Dim shared As long longvar(elements)
Dim shared As integer intvar(elements)
Dim shared As longint longintvar(elements)
Dim As long tmp, ms
Dim As longint sumi, suml, sumli
Dim As double ti, tl, tli
for n as integer=0 to elements-1   ' create an array of random integers and longs
   tmp=Rnd()*16
   longvar(n)=tmp
   intvar(n)=tmp
   longintvar(n)=tmp
next

'print "Benchmark:"
sleep 10 'short break before benchmark

ti=Timer()
for n as integer=0 to elements-1   ' sum of integers
   sumi+=intvar(n)
next
ti=Timer()-ti

tl=Timer()
for n as integer=0 to elements-1   ' sum of longs
   suml+=longvar(n)
next
tl=Timer()-tl

tli=Timer()
for n as integer=0 to elements-1   ' sum of longints
   sumli+=longintvar(n)
next
tli=Timer()-tli

ms=1000*ti
Print "Sum integer =";sumi;" added in";ms;" ms"
ms=1000*tl
Print "Sum long    =";suml;" added in";ms;" ms"
ms=1000*tli
Print "Sum longint =";sumli;" added in";ms;" ms"

print
sleep
I skipped the Windows part because I don't like Windows and Windows does not like me:
Image
Tested with 3 laptops + 1 desktop PC:

Dell laptop E7450 (2015) Ubuntu 18.04.5 LTS, x86_64
(turbo-boost disabled due to heat problems)

Code: Select all

FreeBASIC 1.07.1 32-bit gas on Linux
Sum integer = 800010752 added in 317 ms
Sum long    = 800010752 added in 313 ms
Sum longint = 800010752 added in 323 ms

FreeBASIC 1.07.1 32-bit gcc on Linux
Sum integer = 800010752 added in 355 ms
Sum long    = 800010752 added in 342 ms
Sum longint = 800010752 added in 344 ms

FreeBASIC 1.07.1 64-bit gcc on Linux
Sum integer = 800010752 added in 343 ms
Sum long    = 800010752 added in 342 ms
Sum longint = 800010752 added in 337 ms
Samsung laptop NP530U3C (2012), Ubuntu 16.04.7 LTS, x86_64

Code: Select all

FreeBASIC 1.07.2 32-bit gas on Linux
Sum integer = 800010752 added in 293 ms
Sum long    = 800010752 added in 294 ms
Sum longint = 800010752 added in 316 ms

FreeBASIC 1.07.2 32-bit gcc on Linux
Sum integer = 800010752 added in 292 ms
Sum long    = 800010752 added in 291 ms
Sum longint = 800010752 added in 317 ms

FreeBASIC 1.07.2 64-bit gcc on Linux
Sum integer = 800010752 added in 326 ms
Sum long    = 800010752 added in 314 ms
Sum longint = 800010752 added in 319 ms
Samsung netbook N210 (2010), Ubuntu 14.04.6 LTS, i686

Code: Select all

FreeBASIC 1.00.0 32-bit gas on Linux
Sum integer = 800010752 added in 804 ms
Sum long    = 800010752 added in 791 ms
Sum longint = 800010752 added in 963 ms

FreeBASIC 1.00.0 32-bit gcc on Linux
Sum integer = 800010752 added in 1090 ms
Sum long    = 800010752 added in 1083 ms
Sum longint = 800010752 added in 1063 ms
Desktop core2duo 3GHz (2008?), Ubuntu 20.04 LTS, x84_64

Code: Select all

FreeBASIC 1.07.1 32-bit gas on Linux
Sum integer = 800010752 added in 335 ms
Sum long    = 800010752 added in 332 ms
Sum longint = 800010752 added in 342 ms

FreeBASIC 1.07.1 32-bit gcc on Linux
Sum integer = 800010752 added in 431 ms
Sum long    = 800010752 added in 427 ms
Sum longint = 800010752 added in 369 ms

FreeBASIC 1.07.1 64-bit gcc on Linux
Sum integer = 800010752 added in 265 ms
Sum long    = 800010752 added in 252 ms
Sum longint = 800010752 added in 263 ms
So only when I process longints on on a 32-bit CPU do I see a significant difference (but only for gas).
Last edited by badidea on Feb 28, 2021 22:48, edited 1 time in total.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Integer data types in 32-bit and 64-bit

Post by jj2007 »

badidea wrote:I did some more tests with a bit modified code:

Code: Select all

#Define elements 100000000 '100M
...
FreeBASIC 1.07.1 64-bit gcc on Linux
Sum integer = 800010752 added in 343 ms
Sum long    = 800010752 added in 342 ms
jj2007 wrote:With 150 Million elements, FB64:

Code: Select all

Sum integer= 1199937252 added in  175 ms
Sum long   = 1199937252 added in  89 ms
My sum long is a factor 5.76 faster. The two CPUs should differ by a factor 2.5 only. So it seems that your 64-bit code is not very efficient under the hood.
badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Integer data types in 32-bit and 64-bit

Post by badidea »

jj2007 wrote:My sum long is a factor 5.76 faster. The two CPUs should differ by a factor 2.5 only. So it seems that your 64-bit code is not very efficient under the hood.
I blame it on the compiler. Note that the turbo-boost is disabled on the Dell, that reduces the maximum clock speed (I forgot the numbers).
I added the results of an ~2008 desktop to the list. Back then, it was a pretty fast (custom build) PC and apparently still the fastest with 64-bit fbc.
If you plan bitcoin mining, don't use my hardware.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Integer data types in 32-bit and 64-bit

Post by dodicat »

You have found a Windows 64 bit bug badidea.
a literal crashes (no optimisations)

Code: Select all

Dim shared As long longvar( 100000000 )
Dim shared As integer intvar( 100000000 )
Dim shared As longint longintvar( 100000000 )
print 100000000
sleep
 
but a variable is OK

Code: Select all

var elements = 100000000

Dim shared As long longvar(elements)
Dim shared As integer intvar(elements)
Dim shared As longint longintvar(elements)
print elements
sleep
 
Win 10
Post Reply