FreeBASIC 1.08 Development

General discussion for topics related to the FreeBASIC project or its community.
Post Reply
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: FreeBASIC 1.08 Development

Post by deltarho[1859] »

I'm back.

I first noticed something 'strange' about PowerBASIC's RND in January 2016. If I used RND in a primary thread and a secondary thread the throughput collapsed. One of the members, Paul Dixon, is an expert on threads, and he wrote: "When both threads call the same code to generate the next number there's a conflict with 2 CPU cores trying to change the same memory locations and the CPU has to re-cache the new number across all the CPU cores before it can continue. In effect, you're repeatedly forcing a cache miss which slows everything down." Sharing the RND code is not an issue but RND uses memory to remember its state vector and that is used on the next call to RND. With RND used in two separate threads the same memory, holding the state vector, is being changed by the two threads and that is where the conflict is.

In the thread 'So, RND is not thread safe then.' Mersenne Twister (MT) comes in at 84MHz. However, if MT is used in a primary thread and a secondary thread the throughput for each drop to 42MHz. MT's state vector is also being changed by the two threads. When I looked at PCG32 I duplicated everything in sight and got no collisions. I wrote that thread in June 2017 only a few months as a member of the forum. St_W introduced me to using procedures in UDTs leading me to PCG32II and I thought it was that when no collisions occurred.

In fact, the reason no collisions occurred was because the state vector was being duplicated and not because the generator was in the UDT. Each time the UDT is used a new memory location is created for the state vector so it will only be changed by the new UDT instance and, therefore, no conflict.

It still makes sense to have the generator as an element of the UDT otherwise we would have to duplicate it but that has nothing to do with collisions.

I no longer disagree with fxm and stand corrected with everything he wrote.

All of FreeBASIC's generators can be made thread safe if each instance can be given a unique memory location for its state vector. That should not be difficult if all the state vectors were the same size, but they are not. However, that should not be unsurmountable. Can I do it? Maybe, but I can think of a few who would get there a lot quicker than me.

Thread local storage? I am not acquainted with that but is sounds interesting.

So, who needs a thread safe RND anyway? Not many but coderJeff is looking at it and, I cannot remember which, but two languages at least have thread safe generators, and they did not develop them for the fun of it. Image

Added:
Yours truly wrote:So, if pcg32A and pcg32B are seeded differently then not only are we using two separate sequences we are using different sequences.
I then wrote: "It would seem that is also false. It looks like we are using the same sequence but different entry points."

Oh dear, that is wrong. PCG32 uses a seed and a sequence number. If pcg32A and pcg32B use a different sequence number then we are using different sequences. The state vector is seed and sequence. If we use the same sequence number but a different seed then we are using the same sequence but different entry points. It is amazing what we forget as time marches on.

Corection: In the last paragraph I wrote "The state vector is seed and sequence." That should read "The state vector is state and sequence." The initial state is the seed and it gets updated on each random number request. Even that is not strictly true because the generator is warmed up by burning a bunch of outputs before releasing any random numbers to us.
Last edited by deltarho[1859] on Oct 05, 2020 4:28, edited 2 times in total.
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: FreeBASIC 1.08 Development

Post by deltarho[1859] »

I have been looking at TLS and it looks a bit heavy to me.

It is worth remembering that each thread has its own stack. Perhaps we can make use of that. Just an idea - probably barmy.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC 1.08 Development

Post by fxm »

fxm wrote:When a new UDT instance is created, the code of the member procedures is not duplicated (only non-static data members are duplicated).
Now this is pointed out in the Programmer's Guide:
ProPgUDTs → fxm [added small paragraph 'UDT Instantiation']
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: FreeBASIC 1.08 Development

Post by coderJeff »

deltarho[1859] wrote:I have been looking at TLS and it looks a bit heavy to me.

It is worth remembering that each thread has its own stack. Perhaps we can make use of that. Just an idea - probably barmy.
Yeah, TLS is not too bad.

I tried a mutex implementation with some extra runtime API functions that bypass conditionals and conversions. But still uses one state for the RNG so lots of time is spent competing for a lock on the RNG regardless, and still uses some pointer indirection and function calls, which I think is unavoidable in fbc.

For maximum bandwidth, would be looking for something that uses thread local storage, is inline, no pointer indirection, no function calls, no unnecessary conversions, and no conditionals.

We can't do the ideal for a few reasons:
- freebasic has no inline functions (#macro's maybe can fake it out though).
- pointer look-ups and function calls needed due to RANDOMIZE and RND() mapping to multiple RNG's.
- conversions to double due to traditional RND() as double usage in freebasic
- RND(arg) preforms a conditional on arg for alternate behaviour - return new number or last number.

I think with TLS at least we will at least get rid of a mutex lock bottleneck. It will be at least thread-safe and best we can do given other limitations. With a few extra API functions, might be able to shave off a few cycles for unnecessary computations. For users that really want to optimize a RNG, custom implementations are probably still going to win the performance race. But, I have no idea what the comparison will be until I write it and try it out.
Mysoft
Posts: 836
Joined: Jul 28, 2005 13:56
Location: Brazil, Santa Catarina, Indaial (ouch!)
Contact:

Re: FreeBASIC 1.08 Development

Post by Mysoft »

heh among the things i was trying to get to work with freebasic, but without success they were "intrinsinc" instructions...
like i could even get SOME working i.e.

Code: Select all

declare function __popcnt cdecl alias "__builtin_popcount" (n as integer) as integer
print __popcnt(3)
but i can't get...

Code: Select all

declare function _paddb cdecl alias "__builtin_ia32_paddb" (as v8qi, as v8qi) as v8qi
to work because of the type v8qi will end as different declarations

and since i can't inline C, i can't adjust the C code to accept those, not that freebasic would like the SSE ones, since there isnt a 16 byte datatype at all.. but having such capabilities would be helpful... (same goes for inlined functions, which are useful when cross compiling as well)

ofcourse i can hack those around with a "C preprocessor", but i wonder what would be the effort to at least allow certain capabilities from C to be used on freebasic.

and ofcourse one thing that is a lot of work, would be to have freebasic compiler, to be usable as a DLL, so that one can integrate it on IDEs, i remember DKL tried to get it to work but it was too much effort, but still its one of the major things that would be incredible handy.
adeyblue
Posts: 300
Joined: Nov 07, 2019 20:08

Re: FreeBASIC 1.08 Development

Post by adeyblue »

I thought about implemening these (mainly because I wanted to use the __sync builtins instead of a full-blown mutex for something) but as far as my skills reach in hacking FB, they'd have to be exposed from the main library, which means they'd have to be called, which sort of defeats the purpose of using them. So I gave up
Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: FreeBASIC 1.08 Development

Post by Lost Zergling »

The idea of ​​using the compiler as a dll looks nice, especially regarding the possibility of on-the-fly compilation which could become an instruction on a string variable, in the code. From this point of view, Gas which is suitable for fast compiling, might seem an idea.
I'd like to say next version is eagerly awaited, as it is announced to introduce progress on the capabilities of FB. To my point of view, mutex problematics are potentially endless as it is a balance between transactional and delay constraints, wich are linked each others.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: FreeBASIC 1.08 Development

Post by jj2007 »

Mysoft wrote:to have freebasic compiler, to be usable as a DLL, so that one can integrate it on IDEs, i remember DKL tried to get it to work but it was too much effort
Can you elaborate on that idea? What be the advantage of having FB as a DLL, compared to the standard usage in an IDE, i.e. create a FB process and pipe its output to the IDE?
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC 1.08 Development

Post by dodicat »

Maybe it is the modern way, certainly python can be used via dll(s)
viewtopic.php?f=14&t=27718&p=262155&hil ... on#p262155
Oxygen basic is a dll type compiler, Is Oxygen basic based on a freebasic dll?
I remember something from a few years back, I think it was done, but I could be wrong.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: FreeBASIC 1.08 Development

Post by jj2007 »

dodicat wrote:Maybe it is the modern way, certainly python can be used via dll(s)
viewtopic.php?f=14&t=27718&p=262155&hil ... on#p262155
That thread ended with "I'll mess around with it later" ;-)
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: FreeBASIC 1.08 Development

Post by caseih »

jj2007 wrote:
Mysoft wrote:to have freebasic compiler, to be usable as a DLL, so that one can integrate it on IDEs, i remember DKL tried to get it to work but it was too much effort
Can you elaborate on that idea? What be the advantage of having FB as a DLL, compared to the standard usage in an IDE, i.e. create a FB process and pipe its output to the IDE?
The idea of a compiler as a shared library is quite a common one, and it's super useful, especially in editing and debugging. Visual Studio, for example, can recompile sections of code and replace them in memory while the program is running in the debugger. While you could do that by calling a compiler, doing it as a DLL is more dynamic and finer-grained. This allows live code changes while developing in a compiled, statically-typed language. Also since the compiler's state would be kept alive in memory, there's flexibility for the user of the DLL to access the syntax tree and symbol tables, all of which are useful for a debugging environment, and also intelligent code completion and context-sensitive code help. An example of the latter is Visual Studio's IntelliSense. That's all powered by a compiler as a shared library.

Another area that a compiler as a DLL is helpful is in building a JIT compiler for an otherwise interpreted language.

I believe the llvm compiler suite works as a shared library, which is one reason it's found so many wide and varied uses. dotnet's compilers have been available as callable shared libraries since the beginning.
Last edited by caseih on Dec 17, 2020 17:29, edited 2 times in total.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: FreeBASIC 1.08 Development

Post by jj2007 »

Thanks, caseih, that's interesting.
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: FreeBASIC 1.08 Development

Post by caseih »

As I think about it, all modern IDEs essentially use compilers as libraries. Either they use an existing compiler as a library (like llvm) or implement the compiler themselves in the editor. That's the only way to get complex type and symbol information, especially with a complex language like C++. Visual Studio essentially compiles as you type. I'm sure most other fancy IDEs do the same, even if they call out to a "real" compiler to get the actual executable. The line between IDEs and compiler is really blurry these days! Theoretically FB as a library would allow for FB IDEs with code completion and help with function parameters, type members, etc.
marcov
Posts: 3462
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: FreeBASIC 1.08 Development

Post by marcov »

caseih wrote:As I think about it, all modern IDEs essentially use compilers as libraries. Either they use an existing compiler as a library (like llvm) or implement the compiler themselves in the editor. That's the only way to get complex type and symbol information, especially with a complex language like C++. Visual Studio essentially compiles as you type. I'm sure most other fancy IDEs do the same, even if they call out to a "real" compiler to get the actual executable. The line between IDEs and compiler is really blurry these days! Theoretically FB as a library would allow for FB IDEs with code completion and help with function parameters, type members, etc.
I know of _old_ Delphi (<=7) that there the compiler does the information gathering for codetools/intellisense. Afaik most IDEs, including newer Delphi's have a separate parser for that.

One of the big problems of recycling compilers for intellisense is that they usually give up way too easily on minor syntactic errors, and are not designed to parse both legs of an IFDEF..ELSE conditional block. IDE parsers therefore are designed to keep on trying despite errors.
Last edited by marcov on Dec 29, 2020 15:09, edited 1 time in total.
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: FreeBASIC 1.08 Development

Post by coderJeff »

In my dreams freebasic has edit & continue. Unfortunately there are many obstacles to overcome to get there.

Making fbc into a DLL is not that hard. Rather than a "main" executable entry point that parses command line options, provide an alternate procedure entry point that does the same thing. However, this is only one step though as the ultimate product will continue to be assembly listings, either directly through the ASM emitters or indirectly through the other emitters. In the end, without a lot of other additions, fbc is calling other tools to compile / assemble / link. i.e gas, gcc, ld, etc.

Initially, making fbc in to a DLL would at least allow for a mechanism (for example, through call-backs) to get additional information to the caller (for example, an IDE), while compilation is happening. However, fbc produces assembly listings that are processed by other tools. fbc doesn't do any address allocation. The listing is still symbolic in terms of where procedures and global variables are positioned in memory.

To make fbc in to something that can compile and execute immediately, or possibly have an "immediate mode" that can execute statements inside a stopped program, fbc would need to emit to some kind of virtual machine code (i.e. byte code / pseudo code), in which case fbc needs to be able to allocate static variables, track pointers, procedure addresses, etc. In this kind of execution model, no static libraries could be used: either everything needs to be integrated in to the caller (statically) or loaded only from DLL's (kind of like how VB can call any DLL function with proper declare but can't link to static libraries).

To further extend to possibility of edit and continue, fbc would need to track the pseudo compiled code fragments in a way where sections of code can be recompiled and replaced while execution (of the virtual machine) is suspended.

In otherwords my opinion is that making fbc a DLL is only just the *very* beginnings of doing something interesting with the compiler as a component rather than a main program.
Post Reply