Threading questions/problems
-
- Posts: 8642
- Joined: May 28, 2005 3:28
- Contact:
Re: Threading questions/problems
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
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.
Re: Threading questions/problems
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:
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)
Re: Threading questions/problems
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.
-
- Posts: 8642
- Joined: May 28, 2005 3:28
- Contact:
Re: Threading questions/problems
@fxm without the mutex pset will crash here but only sometimes !
Joshy
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.
-
- Posts: 8642
- Joined: May 28, 2005 3:28
- Contact:
Re: Threading questions/problems
@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
and use the WindowTitle or console output for your time measurement output.
Happy coding :-)
Joshy
-
- Posts: 8642
- Joined: May 28, 2005 3:28
- Contact:
Re: Threading questions/problems
@fxm you are right i removed the mutex stuff and it works.
it was a problem with maximum recursion while testing.
Joshy
it was a problem with maximum recursion while testing.
Joshy
Re: Threading questions/problems
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!
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
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!
Note 2Version 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)
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)
Re: Threading questions/problems
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.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)
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
Re: Threading questions/problems
Regression since fbc version 1.00.0: ThreadCall fails when we pass a literal string (either byref or byval)
Simple example:With fbc version 0.90.1:With fbc version 1.00.0:
Is it linked to the change on "BYVAL AS STRING" for passing parameters?
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
Code: Select all
1244900
3351904
Threadcall OK
Code: Select all
1244900
0
Re: Threading questions/problems
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)?
[edit]
After other tests, it seems that ThreadCall does not support to be called inside a loop!
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
After other tests, it seems that ThreadCall does not support to be called inside a loop!
Re: Threading questions/problems
If I add a sleep statement to the calling loops:
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:
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.
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
Code: Select all
0123456789
0123456789
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.
Re: Threading questions/problems
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.
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.
Re: Threading questions/problems
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
Re: Threading questions/problems
KeyPgThreadCall ⇒ FxMwikki [Added warning about the present design]
Re: Threading questions/problems
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!
- 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...