Multithreaded PAWN using just standard NPCs
#1

Im messing around with NPCs more and more, and a while ago I had an idea of abusing NPCs for something not new, but useful.
You probably know that sa-mp's NPCs are running in their own process, samp-npc(.exe). Because of this they also run in their own thread, completely independent from the samp server. But you can still communicate bewteen the servers script, and the NPCs script using messages, commands, etc. So why no abuse this, and let a NPC calculate intensive tasks, while the server keeps focused on his main task.

The idea is extremely easy, though I havent read about it in the forum yet (or missed it somehow).
The NPC script contains the OnClientMessage callback that reports all clientmessages that are sent to the NPC. In this callback you wait for a specific "task code" sent by the server, to execute some task, let it be a simple chat answer, or a complex calculation that takes minutes. During that time the server of course wont lag, as samp-npc runs the calculating thread. When the task is finished, you can report the result to the server using commands or chat messages, and again include the "task code". If the server now receives a message by a NPC, that contains a known task code, he can e.g. call the OnLongTask1Finished(result) callback.
In reality "exporting" short tasks doesnt pay out of course. Parsing the parameters out of the sent message takes some time on NPC and server side of course, so the threaded task might take way longer than it would in the normal server thread.
Another big problem is the separated memory. Because NPC and server run in their own processes, they cant access each others variables, functions, etc. This limits the jobs the "thread npcs" could do a lot. They also cant change server properties like spawning cars, affecting other players etc, unless they sent another code to the server, that tells him to do it, but this will be really messy and inefficient.
Nevertheless, I think that there are a lot of things that could profit from this kind of multithreading.

I tested some examples, and as it seems samp-npc is even faster than the server in some cases. A simple floatsqroot based GetPointToPoint is up to 300% faster as threaded task in the NPC script, than on the server. However this does not include time for parsing the parameters.

For testing I used my RNPC include/NPCmode as they already provide a good npc<->server communication
Reply
#2

I like the idea!
But wouldn't you have to ask the SA-MP team to mess around with samp-npc?
They probably would find it "abusing" like you said.
Reply
#3

I just called it abusing, as the NPC wouldnt be used as a NPC, but just as something like a virtual thread. Those thread NPCs could even still be used as normal NPCs, but they would lag when they run a task, as the npc script also is just single-threaded and cant control the npc and calculate something at once
All this is done without touching any of the executable files, the memory, or whatever, just with scripting methods, so I guess it shouldnt be a problem.
Reply
#4

I guess the communication between server and NPC might be longer than any some (medium sized) threads can be done by the server itself.

If you like to use it to send data to another client to calculate on its own thread for example expensive hashing, handling large files, some other procedure which surely would hold the thread on the server you can simply use the socket plugin to get the results send back to server server and readable over a callback in your script.
Reply
#5

What sort of calculations would be done in SA-MP that's big enough for this? Not to mention they may not use plugins, file I/O, DBs, and more.
Communication would be quite bad, too. Transfering raw data, for example, would have to be encoded to take in account the NULL char. Not to mention the max length of client messages, which would be even a bigger problem.
Reply
#6

I had an idea to do something similar but I had no uses for it.

I'm curious to see someone put together some benchmarks of where this could be useful, I might try this myself. Maybe a PAWN based streamer running in the NPC process? Anyone have any other ideas?
Reply
#7

As this script is not running in the main server, CallRemoteFunction could be used?
If this function does still work, this is just epic, if not the comunication between the server and the NPC should be using SendCommand processing the result on OnPlayerCommandText as this is the less visible effect for the server's users.
Reply
#8

An usage example would be path finding with lots of nodes. This might take several 100ms or even seconds and so cant be used efficiently. Putting this in a NPC process is no problem then, you just need to wait for it to finish.
Node data needs to be reloaded in the NPC script which wastes some RAM but I think thats worth the speed boost.
Reply
#9

Quote:
Originally Posted by Mauzen
View Post
An usage example would be path finding with lots of nodes. This might take several 100ms or even seconds and so cant be used efficiently. Putting this in a NPC process is no problem then, you just need to wait for it to finish.
Node data needs to be reloaded in the NPC script which wastes some RAM but I think thats worth the speed boost.
I recently finished a GPS script that uses A* for path finding, it runs between 40-60ms each route, the only exception being if it can't find a path and is forced to check all nodes in which case it takes about 400ms.
This is a long time for a script to run however I feel it could be greatly optimized if some one with more path finding knowledge was to work on it.
For example the nodes in gta are split into 64 sections, I believe these grids were used initially to create a rough path and then it would be refined more.
Reply
#10

I just stumbled upon this thread when searching for something else.
Now 2 years later I actually made use of that idea in RNPC.

I use the NPC processes to check for players in a certain range around the NPC, to use that information in the gamemode process, and for my purpose those checks have to run quite often (<200ms intervals)
Checking for close players will, in the big majority of the cases, return no result, as most of the time most players wont be near the NPC. Still that distance checks are a quite heavy task for a server with many players and/or many NPCs.
Communication is realized over a command that is sent to the server to notify about any players within the range, so that event can then be handled by the server (in my case, check whether the players vehicle is standing directly on the NPC, or driving over it).
I really dont know how much work exactly it is for the server to receive and handle an incomming command, but Im pretty sure that the communication overhead is much lighter than running all the checks directly on the server, considering the rareness of the event and the high frequency of the checks.

Also, now that there is the possibility/knowledge to create NPC plugin and so greatly expand the power of NPC scripts, I thought it would be worth reviving a two years old thread, cant harm to have that concept in your stock.
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)