Threading questions/problems

New to FreeBASIC? Post your questions here.
D.J.Peters
Posts: 8642
Joined: May 28, 2005 3:28
Contact:

Re: Threading questions/problems

Post by D.J.Peters »

A more real life and beauty threading test you can play with the number of running threads (set MAX_THREADS).

You can set SAMPLES_PER_PIXEL to a higer value for high quality images also.
(SAMPLES_PER_PIXEL =256 needs some hours here)

Every red line is a running render thread.

Global Illumination rendering. (CPU killer)

Joshy
Last edited by D.J.Peters on Feb 08, 2015 16:06, edited 2 times in total.
fxm
Moderator
Posts: 12577
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Threading questions/problems

Post by fxm »

A local mutex in each thread is useless!
A mutex must be shared between threads to be efficient.

In your case, any mutex is useless, because you must use fbc version 1.01.0:
[added] in fbc version 1.00.0:
- Thread-safe version of the FB graphics library (libfbgfxmt), used automatically if FB's threading functions are used or fbc's -mt command line option is given, just like the thread-safe version of the FB runtime library (libfbmt)
Provoni
Posts: 525
Joined: Jan 05, 2014 12:33
Location: Belgium

Re: Threading questions/problems

Post by Provoni »

Beautiful output for such a short program D.J.Peters. Is it possible to exclude the red lines from the screenshot and to include a time elapsed? I'll play around with it when the dual CPU system has finished its jobs.
D.J.Peters
Posts: 8642
Joined: May 28, 2005 3:28
Contact:

Re: Threading questions/problems

Post by D.J.Peters »

@fxm without the mutex pset will crash here but only sometimes !

Joshy
fbc wrote:D:\fbExamples\fb3D>fbc -version
FreeBASIC Compiler - Version 1.01.0 (12-28-2014), built for win32 (32bit)
Copyright (C) 2004-2014 The FreeBASIC development team.
standalone
Last edited by D.J.Peters on Feb 08, 2015 12:33, edited 1 time in total.
D.J.Peters
Posts: 8642
Joined: May 28, 2005 3:28
Contact:

Re: Threading questions/problems

Post by D.J.Peters »

@Provoni of course you can comment out the LINE command
and use the WindowTitle or console output for your time measurement output.

Happy coding :-)

Joshy
D.J.Peters
Posts: 8642
Joined: May 28, 2005 3:28
Contact:

Re: Threading questions/problems

Post by D.J.Peters »

@fxm you are right i removed the mutex stuff and it works.

it was a problem with maximum recursion while testing.

Joshy
fxm
Moderator
Posts: 12577
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Threading questions/problems

Post by fxm »

Note 1
The program hangs if compiled with a fbc version < 1.00.0, even using a shared true mutex (lock, unlock) around the graphic instructions of the thread!
Version 1.00.0 (former 0.91.0):
[added]
- Thread-safe version of the FB graphics library (libfbgfxmt), used automatically if FB's threading functions are used or fbc's -mt command line option is given, just like the thread-safe version of the FB runtime library (libfbmt)
Note 2
To compile program with a fbc version < 1.01.0, add parentheses in the following line:
dim as Ray cam=Ray(Vec(50,52,295.6),(Vec(0.0,-0.1,-1)).norm()) ' cam pos, dir
Version 1.01.0:
[added]
- #757: It's now possible to do UDT().field instead of (UDT()).field (field accesses on anonymous UDTs with constructors)
fxm
Moderator
Posts: 12577
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Threading questions/problems

Post by fxm »

fxm wrote:Note 1
The program hangs if compiled with a fbc version < 1.00.0, even using a shared true mutex (lock, unlock) around the graphic instructions of the thread!
Version 1.00.0 (former 0.91.0):
[added]
- Thread-safe version of the FB graphics library (libfbgfxmt), used automatically if FB's threading functions are used or fbc's -mt command line option is given, just like the thread-safe version of the FB runtime library (libfbmt)
By adding also mutex (lock, unlock) around the graphic instructions (Windowtitle) of the main program (main thread executing the main program) in each main program loop while the other threads run.
Now the program works as I thought that it should.

See the last program version so modified at:
http://www.freebasic.net/forum/viewtopi ... 90#p205090
fxm
Moderator
Posts: 12577
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Threading questions/problems

Post by fxm »

Regression since fbc version 1.00.0: ThreadCall fails when we pass a literal string (either byref or byval)

Simple example:

Code: Select all

Sub thread (Byref s As String)
  Print @s
  Print Strptr(s)
  Print s
End Sub

Dim As Any ptr p = Threadcall thread("Threadcall OK")
Sleep
With fbc version 0.90.1:

Code: Select all

1244900
3351904
Threadcall OK
With fbc version 1.00.0:

Code: Select all

1244900
0
Is it linked to the change on "BYVAL AS STRING" for passing parameters?
fxm
Moderator
Posts: 12577
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Threading questions/problems

Post by fxm »

It's worse, I do not understand anything!
ThreadCall with multiple threads (with numeric parameter) fails whatever fbc version!
Where is my mistake (I have not habit to use ThreadCall)?

Code: Select all

Dim Shared As Any Ptr m
m = Mutexcreate()
Dim As Any Ptr p(9)

Sub thread (Byval p As Any Ptr)
  Mutexlock(m)
  Print Str(p);
  Mutexunlock(m)
End Sub



For I As Integer = 0 To 9
  p(I) = Threadcall thread(Cast(Any Ptr, I))
Next I
For I As Integer = 0 To 9
  Threadwait(p(I))
Next I
Print

For I As Integer = 0 To 9
  p(I) = Threadcreate(@thread, Cast(Any Ptr, I))
Next I
For I As Integer = 0 To 9
  Threadwait(p(I))
Next I
Print

Sleep

Code: Select all

1256777999
0214365789
[edit]
After other tests, it seems that ThreadCall does not support to be called inside a loop!
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Re: Threading questions/problems

Post by MichaelW »

If I add a sleep statement to the calling loops:

Code: Select all

#include "windows.bi"

Dim Shared As Any Ptr m
m = Mutexcreate()
Dim As Any Ptr p(9)

Sub thread (Byval p As Any Ptr)
  Mutexlock(m)  
  ''print GetThreadPriority(GetCurrentThread())  
  Print Str(p);
  Mutexunlock(m)
End Sub

''print GetThreadPriority(GetCurrentThread())  

For I As Integer = 0 To 9
  p(I) = Threadcall thread(Cast(Any Ptr, I))
  sleep 10
Next I
For I As Integer = 0 To 9
  Threadwait(p(I))
Next I
Print

For I As Integer = 0 To 9
  p(I) = Threadcreate(@thread, Cast(Any Ptr, I))
  sleep 10
Next I
For I As Integer = 0 To 9
  Threadwait(p(I))
Next I
Print

Sleep
Then compiling as a 64-bit app with FreeBASIC Compiler - Version 1.02.0 (01-12-2015), built for win64 (64bit), or as a 32-bit app with FreeBASIC Compiler - Version 0.90.1 (07-17-2013) for win32, everything works as expected:

Code: Select all

0123456789
0123456789
If I uncomment the lines that display the thread priority I get 0 (= THREAD_PRIORITY_NORMAL). I think the problem, at least for my system, is that all of the threads have the same scheduling priority, so the context switch (between the threads) happens at the end of the current timelice, and the length of a timeslice is ~~20ms, according to Microsoft.

Edit2: My analysis must be wrong, increasing the priority of the new threads, which should allow them to preempt the original thread, does not correct the problem.
Last edited by MichaelW on Feb 14, 2015 18:13, edited 2 times in total.
dkl
Site Admin
Posts: 3235
Joined: Jul 28, 2005 14:45
Location: Germany

Re: Threading questions/problems

Post by dkl »

There are some problems with the current ThreadCall implementation.

For example, temporary objects: If the ThreadCall involves temporary objects (strings, UDTs) that will be passed (byref) to the thread, then there is a race condition. The temporary objects will be destroyed at the end of the ThreadCall statement, but there is no guarantee that the thread (which wants to access them) is launched and running by then.

Regarding temporary strings, there was a change in 1.00.0. Previously, the temp strings were leaked, and since 1.00.0 they're freed at the end of the ThreadCall statement (this commit). So temp strings were working before, by beaing leaked (which isn't exactly good though).

However, overall the same problem exists for temp UDT objects. Their behaviour didn't change (they were not "working" before like temp strings). That was the reason why I decided to make that change for temp strings.

As far as the loop iterator issue is concerned, there apparently is a similar issue: it's being passed byref internally, so by the time the thread is started, it may see a different value than intended, because the iterator could have been incremented already... that's basically the same issue as with the temp objects.

It seems to me like all of this can only be fixed by reimplementing ThreadCall in such a way that it will take all objects intended for the thread and duplicate them for the thread.
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Re: Threading questions/problems

Post by MichaelW »

I think that explains the problem I had with the ThreadCall example from the FB-manual. The code works OK when compiled as a 32-bit app with FreeBASIC Compiler - Version 0.90.1 (07-17-2013) for win32, but compiled as a 64-bit app with FreeBASIC Compiler - Version 1.02.0 (01-12-2015), built for win64 (64bit), the strings don't display:

Code: Select all

thread             1/4
thread             1/6
thread             2/4
thread             2/6
thread             3/4
thread             3/6
thread             4/4
thread             4/6
thread             5/6
thread             6/6
fxm
Moderator
Posts: 12577
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Threading questions/problems

Post by fxm »

KeyPgThreadCall ⇒ FxMwikki [Added warning about the present design]
fxm
Moderator
Posts: 12577
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Threading questions/problems

Post by fxm »

I think there is another problem in the following example:
- The fault is not the rapid incrementation of the displayed values of the global iterator because it is passed by reference (there is no temporary variables involved by ThreadCall).
- The real fault is that program crashes before end!

Code: Select all

Dim Shared As Any Ptr m
m = Mutexcreate()
Dim As Any Ptr p(9)
Dim Shared As Integer I

Sub thread (Byref K As Integer)
  Mutexlock(m)
  Print @K, Str(K)
  Mutexunlock(m)
End Sub

Print @I
Print
For I = 0 To 9
  p(I) = Threadcall thread(I)
Next I
For J As Integer = 0 To 9
  If p(J) = p(J) Then
  End If
Next J

Sleep

Code: Select all

4239396

4239396       3
4239396       8
4239396       10
4239396       10
4239396       10
4239396       10
4239396       10
9             Appuyez sur une touche pour continuer...
Post Reply