Ease thread execution
#1

Well, I was preparing myself for writing a quite simple speedometer for my RPG Gamemode and something came up on my mind while designing the layout of data checking->assigning.
I thought about checking, time by time, a static type variable of a timestamp from last speed check and, then, if some considerable amount of time has passed since last check, call a 1 millisecond timer for a checking function for each player.

As you must know, Pawn is single-threaded and, the amount of code you write in some public function is equivalent to the time the whole gamemode/filterscript thread will 'freeze', executing it. That means if some player types a /command during loading one thousand houses from a MySQL database, it will take a while to the server to process the command.

With this layout, we can create some 'subthreads' as the process described up there is very similar to the way windows (as an example) simulates multithreading on single-cored processors (as I'm not sure how this works on multi-cored processors).

I believe this isn't a bad choice, but I'd like to hear your opinion about this layout.
I have seen some similar code on here, but if this is a topic already discussed, my apologies.
And sorry for my bad English.
Reply
#2

Why not just use a longer timer like everyone else?
Reply
#3

Oh yeah. Why searching for ways to improve overall scripting performance?
I'm not sure if you got the topic point, but I'd like to collect thoughts on this, like a discussion. This may be good, or just stupid. I want to know that and I want to know why, like any other discussion.
Reply
#4

Quote:
Originally Posted by Stewie`
View Post
I thought about checking, time by time, a static type variable of a timestamp from last speed check and, then, if some considerable amount of time has passed since last check, call a 1 millisecond timer for a checking function for each player.
I don't see how that is any different than setting a timer for "a considerable amount of time".
Reply
#5

Thanks for your input.
Reply
#6

Maybe I'm just being thick - if you want to stimulate discussion it might help to clarify what you mean.
Reply
#7

i bet he means "multitasking" in the sense that a process (updating speedometer in a textdraw) gets triggerd after, lets say, 400 ms, but the timer running the checks for the timestamp, would run @ 20ms.
20ms timer runs 19 times "for nothing" (nothing equals no CPU time wasted also),
and at the 20th run it would calculate the timestamp being too old: update textdraw.
imo, a good trick for doing such things, is to use ONE short timer for all that - like 100 timers running @ 10 ms would cause major CPU-waste due to the context switching (suxx hard on windows)

good idea to discuss about that btw, iam always curious on finding better ways to let 1 thread like "load/save 10000 houses" working in background.

addition: i once tested that multithread plugin by frosha, i had some crashes as expected and mentioned, but another time it didnt crash at all for some reason. it had something to do with the timer type, and if the used callback contained ANY return; (now i remember: a threaded callback is/was? not supposed to return)

more thoughts please!
Reply
#8

No, if the multithreaded plugin crashes or not is entirely random - if it does one day and doesn't the next, that's just the nature of trying to add threads to PAWN.
Reply
#9

I figured, let's say we have a public function and it takes 200ms to run, so the gamemode/filterscript thread will freeze over 200ms.

So for example: 20 players execute 20 commands, 5 of them are from homes and take around 500ms, 10 of them are simple commands and takes 100ms, the other 5 will be with database connection and take 300ms, then the total would 5000ms then the gamemode thread would freeze during 5000ms, which would be 5 seconds.

Sorry for my bad English.
Reply
#10

Actually, I was thinking about breaking the main player loop into queuing with a 1ms timer.
Reply
#11

I think I get what you mean by using a 1ms timer.

pawn Code:
func1()
{
    // Each of these functions takes 4ms to execute, meaning when 'func1' is called, it takes
    func2();
    // this function doesn't really need to be called exactly here, it just needs to be called pretty much at the same time as 'func1'
    // Maybe you call func1 100 times and don't want to have to add 'func3' underneath every call.
    func3();
    func4();
}

someCallback()
{
    func1(); // This function takes an overall of 12ms
}
Easing the load by calling func3 afterwards so other stuff can be done:
pawn Code:
func1()
{
    func2();
    func4();

    defer func3();
}

timer func3[1]() // call it after 1ms
{
    // func3's stuff that takes 4ms
}

someCallback()
{
    func1(); // This function now takes 8ms
    // func3 is called some time afterwards, but the server has a chance to do some other stuff like sync etc.
}
Is that somewhat close to what you are trying to explain?

Obviously you'd have to be very careful with the flow/structure as the code could end up doing something with some variables that are affected in the delayed function meaning they aren't at their correct values when they are accessed. If you understand me (I last slept about 40 hours ago... brain probably doesn't want to do stuff atm)
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)