Well, I liked MrP's way of using ASM to plot a pixel, so I adapted it. I also decided I wanted to try multithreading.
The multithreading is disgustingly faster here, however, the program doesn't wair for old threads to close before opeinig new ones. So that is a potential leak there. No promises your system won't lock up =/ ( Just for reassurance though, it works beautifully here )
To use the multithreading, change the "mode" variable to 1
#define PTC_WIN
#include "tinyptc.bi"
type threadstack
thread as integer
nextthread as threadstack pointer
end type
declare sub putpixel(byval params as integer pointer)
declare sub DrawScreen(byval off as integer)
declare sub DrawScreen2()
dim shared as integer pointer buffer
dim shared as integer threadlock
dim shared as threadstack pointer currentthread
dim shared as integer params(3)
dim as byte mode = 0 ' Setting mode to 1 uses multithreading
threadlock = MutexCreate()
buffer = callocate(640*480,Len(Integer))
ptc_open("test",640,480)
dim as integer t
dim as double ttime
ttime = timer
while inkey$=""
ptc_update(buffer)
if mode = 1 then
t = threadcreate (@DrawScreen,0)
t2 = threadcreate (@DrawScreen,1)
else
DrawScreen2
endif
print 1.0/(timer-ttime)
ttime = timer
wend
sub DrawScreen(byval off as integer)
mutexlock threadlock
dim as integer pointer params
params = callocate(3,Len(integer))
for x=off to 639 step 2
for y=0 to 479
params[0] = x
params[1] = y
params[2] = &hFF0000
putpixel(params)
next
next
mutexunlock threadlock
end sub
sub DrawScreen2()
dim as integer pointer params
params = callocate(3,Len(integer))
for x=off to 639
for y=0 to 479
params[0] = x
params[1] = y
params[2] = &hFF0000
putpixel(params)
next
next
end sub
sub PutPixel(byval params as integer pointer)
dim as integer x,y,colour
x=params[0]
y=params[1]
colour=params[2]
asm
mov eax, [x]
mov ebx, [y]
mov ecx, [colour]
mov edx, [buffer]
imul ebx, 640
add eax, ebx
lea edx, [edx+eax*4]
mov [edx], ecx
end asm
end sub
That's not quite right.Ã, I think you're trying to write the even pixels in one thread and the odd pixels in the other, and then flip the screen, but that's not what you're doing.Ã, Because you have the mutex in DrawScreen, then only one thread at a time is running (only 1 thread can lock the mutex at a time).Ã, You should take the mutex lock out.Ã, Also, since you don't wait for either thread to finish, then the frame rate is only counting how long it takes to create two threads, not how long it takes for each of the threads to finish the job.Ã, Try changing pixel colours to see what's going on.
To fix it you should add
threadwait(t)
threadwait(t2)
to wait for the threads to finish, and remove the two mutexlock/mutexunlock lines.
As long as you have at least Hyperthreading on your CPU you should see some speed-up, maybe up to 50%.Ã, I did some tests with a mandelbrot generator on my HT and it's amazing the speed difference, but with that it's pure computation and no memory accesses, which is why you won't see that much of a speedup.
You're also leaking the data you callocate for each call.Ã, Make sure you use the -mt option when you compile else the two callocates going off at the same time might interfere with each other -Ã, you need a thread-safe runtime library for it to work reliably.
Jim
Thanks for the help, I changed a couple things and relized that with all of the memory access, it's actually quite a bit slower on my system with the muilt-threading. This being a first attempt and all, It was destined to not work quite right :)
Maybe if you change one thread to do the top half of the screen and the other half to do the bottom it will be better?
Anyway, because of all the computation, there's definitely an opportnuity to use multithreading to speed up your water sim. I'd like to see that. :D
Jim