Posted: Fri Mar 04, 2005 3:38 pm Post subject: [Tutorial] Processes Part 2 – Normalizing Execution
Processes Part 2 - Normalizing Execution
In the previous tutorial I covered the basics of using processes in Turing. This is an in depth view and implementation of their functionality.
The idea behind processes is to create a concurrent system - a program that would have multiple processes running in parallel and accomplish different tasks closely to one another. This by no means speeds anything up. It is better to think of it as spreading the CPU time over more than one task, so instead of having player1 move and then wait for player2 to do its calculations, both processes take turns processing bits and wait for each other. In a perfect world, both would run in parallel, but alas it is not the default case.
Turing:
process player (ID :int) var x :real:=0 loop Draw.FillBox(0, 10 + ID *10, round(x),15 + ID *10, ID*5)
x +=0.1%decrease the value to slow down if x >= maxxthen put"player", ID, "::",Time.Elapsed return endif endloop end player
for i :1.. 20 fork player (i) endfor
The above code races 20 processes against each other.
In a sample case (x += 0.01), the fastest process has finished half a second before the slowest one (32797 vs 33219), but try it out for yourself. Deviations accumulate over time. This sample 30 second run yielded 1.3% difference. Divergence increases with the number of processes present. Although you might think that 1.3% is insignificant, that advantage will be amplified if one player is 1% faster, 1% stronger, 1% more accurate, and 1% some other way better than the next guy. And this is just with 20 processes. Increased number of objects will make calculations very inconsistent.
A way to normalize all of those processes is needed.
I was going to go for something complex, but the accident solution works quite well for now.
Turing:
loop exitwhenfalse endloop
That's right. Stick that at the end of your program. Virtually no CPU time is lost since it's a single bitwise comparison, but processes are put in place. I cannot explain this yet, just take a look yourself.
Turing:
process player (ID :int) var x :real:=0 loop Draw.FillBox(0, 10 + ID *10, round(x),15 + ID *10, ID*5)
x +=0.1%decrease the value to slow down if x >= maxxthen put"player", ID, "::",Time.Elapsed return endif endloop end player
for i :1.. 20 fork player (i) endfor
loop exitwhenfalse endloop
The difference between fastest and slowest processes has be reduced 10 times and overall (average time between the two extremes) was faster for a sample normalized process group.
fork_5.jpg
Description:
Filesize:
24 KB
Viewed:
8549 Time(s)
fork_4.jpg
Description:
Filesize:
23.33 KB
Viewed:
8543 Time(s)
Sponsor Sponsor
ssr
Posted: Fri Mar 04, 2005 11:35 pm Post subject: (No subject)
ooo
tnx for the tutorial
8)
Shyfire
Posted: Tue Apr 19, 2005 9:46 am Post subject: (No subject)
i still dont see how that normalizes the processes¿
i'm lost¿¿¿¿¿
Tony
Posted: Tue Apr 19, 2005 12:27 pm Post subject: (No subject)
fatboi wrote:
i'm lost¿¿¿¿¿
you must have forgotten to try out the code. I attached an additional screenshot for you.
MysticVegeta
Posted: Sat May 14, 2005 10:48 am Post subject: (No subject)
fork process1 and process2
turing crashes
Cervantes
Posted: Sat May 14, 2005 11:46 am Post subject: (No subject)
Must you post this everywhere? Really, it's not that amazing. Furthermore, I don't even get the crashing.
[Gandalf]
Posted: Sat May 14, 2005 3:38 pm Post subject: (No subject)
Amazing... I must have overlooked this tutorial before, it really helps.
I guess process' are not so evil anymore, are they
Cervantes
Posted: Sat May 14, 2005 4:15 pm Post subject: (No subject)
[Gandalf] wrote:
I guess process' are not so evil anymore, are they
A minor adjustment in emphasis:
I guess processes are not so evil anymore, are they
----
They're not as bad, if you use this technique. But the fact still remains that you don't know how your program will execute.
The big downside, however, to this is that it sort of limits you to ONLY using processes. I say sort of, because the only way that I can find to get this to work nicely is to have the only exit statement as exit when false. That is, you can't exit your loop. If you try to add other conditions, things go wrong with the execution timings.
Let's have some code:
Turing:
var x :=0.0
process player (ID :int) var x :real:=0 loop Draw.FillBox(0, 10 + ID *10, round(x),15 + ID *10, ID *5)
x +=0.1%decrease the value to slow down if x >= maxxthen put"player", ID, "::",Time.Elapsed return endif endloop end player
for i :1.. 20 fork player (i) endfor
loop Draw.FillBox(0, 10 + 21*10, round(x),15 + 21*10, 21*5)
x +=0.1%decrease the value to slow down if x >= maxxthen put"player",21, "::",Time.Elapsed endif exitwhenfalse%or x >= maxx %Try uncommenting the second condition. See how player 21 (the one not in a process) loses? endloop
EDIT: Actually, it seems that putting the exit inside the if x >= maxx then statement of the main loop works fine. Alright, so processes are now more clunky, though they seem to work decently. I still say they should be avoided in most cases.
Sponsor Sponsor
Guest
Posted: Mon Jun 05, 2006 11:07 pm Post subject: (No subject)
You guys are learning to control processes =) That's sweet.
Cervantes
Posted: Wed Jun 07, 2006 11:33 am Post subject: (No subject)
vahnx wrote:
are learning
learned.
Though it needs to be understood that the basic principle of processes means your giving away part of the control flow of your program to the operating system. There are many times that people use processes when they are not necessary. These situations should generally be avoided.
wtd
Posted: Wed Jun 07, 2006 12:30 pm Post subject: (No subject)
In other words:
Know the language. If you know it. then you'll know when it's appropriate to use its various capabiliies.
By the same logic, if you do not know how to appropriately apply language capabilities, then you do not know the language.
Reality Check
Posted: Sat Jun 10, 2006 7:25 pm Post subject: (No subject)
Wait so using that bit of cold you told us, we can use processes now? Does this fix everything or is it just a minor achievment?
[Gandalf]
Posted: Sat Jun 10, 2006 7:39 pm Post subject: (No subject)
It gives you better control of processes when you absolutely need to use them. It doesn't change the fact that in most situations processes are not the best solution to a problem.
Reality Check
Posted: Sat Jun 10, 2006 7:51 pm Post subject: (No subject)
would I be better off putting it all in a loop and calling each thing in procedure?
so:
code:
var x, y, b : int
proc procedure1
drawoval (x, y, z, q, black)
end procedure1
proc procedure2
drawoval (x, y, z, q, green)
end procedure2
loop
Mouse.Where (x, y, b)
if b = 1 then
procedure1
elsifif b = 0 then
procedure2
end if
end loop
Or would it be better to simply draw the ovals inside the ifs themselves? Ofcourse, it will be much more complicated than that with more lines in the 'if' but thats a simplified version. I'm doing a paint program and I read why processes are bad. However, does it matter if they don't occur at the same exact time with a paint? I mean if it were a game where there is collision detect and lives and levels all happening at once than I'd see why that extra bit counts. I posted my paint in the source code section in case you don't get what I mean.
Cervantes
Posted: Sat Jun 10, 2006 8:04 pm Post subject: (No subject)
There is no reason to use processes for a paint type program.
In your example, your procedures are redundent. They do almost exactly the same thing. The minor difference between them can easily be achieved through parameter passing. Furthermore, you shouldn't be using global variables (x, y, z, q) to draw the ovals. Rather, pass them into the procedure.
There seems to be this idea that a procedure is the opposite of a processes; that if you don't use a process, you've got to use a procedure.
Here's the deal. A process allows you to do two tasks simultaneously (though not really, as outlined in these tutorials on processes and why they should be avoided). Chances are, your processes will have loops of their own. So now you can run two loops at the same time (sort of).
If you are going to do this without processes, it means you're doing everything in one loop. This does not mean you have to use procedures. It just means you are only using one loop (not talking about nested loops here -- that's irrelevant to this discussion). Procedures will definately make your loop much more consise and understandable, but they are not necessary. Procedures are just a tool to make this task easier.