1. The forums will be archived and moved to a read only mode in about 2 weeks (mid march).

Is PocketMine a single-threaded application?

Discussion in 'General discussion' started by Legoboy0215, Nov 19, 2016.

  1. Legoboy0215

    Legoboy0215 Witch

    Messages:
    64
    GitHub:
    legoboy0215
    I am not really sure what is the definition of 'threads' here. Does the number of 'cores' and 'threads' in a CPU the same as the 'threads' in PocketMine?
     
  2. falk

    falk Slime Poggit Reviewer

    Messages:
    75
    GitHub:
    falkirks
    Nope, it is multi-threaded.

    But it may just end up running on one core, because PHP is weird like that.
     
  3. Legoboy0215

    Legoboy0215 Witch

    Messages:
    64
    GitHub:
    legoboy0215
  4. falk

    falk Slime Poggit Reviewer

    Messages:
    75
    GitHub:
    falkirks
    Minecraft the game only uses one core because of how it's written.

    They are being stricter than me with the definition of "single-threaded". PocketMine doesn't use threads enough to help performance that much (because PHP isn't built for that). Like you could imagine if you had a website, every person loading the site could be on their own core (if you had an arbitrary amount of cores), but PocketMine doesn't use threads that much. There is one main thread and then threads to generate worlds and handle network stuff.

    The threading in PocketMine exists to prevent the server from breaking because it's trying to serve clients while generating a world, not to make it blazing fast or anything.
     
  5. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    Threads are mainly used to postpone less urgent operations (like world generation) and thread blocking operations (like network operations). It is not a very good idea to try to use many threads just to spread out CPU load for trivial operations like world ticking, etc.

    Note: the above only applies for PocketMine.
     
    ifvictr, falk and HimbeersaftLP like this.
  6. robske_110 (Tim)

    robske_110 (Tim) Wither Skeleton Poggit Reviewer

    Messages:
    1,342
    GitHub:
    robske110
    The main thread is very very busy and other threads are fairly doing anything [Except the RakLib thread] It is very hard to build a threaded MCPE server, because we have to get all our results together in 1/20th of a secound. We do postpone some stuff like world generation or network compression, but it is nearly impossible to do sth like AI async, due to the large amount of managing and synchronization needed.
     
    HimbeersaftLP likes this.
  7. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    More likely, simple fixable livelocks/deadlocks will slow down the server instead.
     
    falk likes this.
  8. aliuly

    aliuly Silverfish

    Messages:
    23
    GitHub:
    alejandroliu
    The main issue with threading is keeping the different threads in sync. The way PHP threading is set-up is that they don't share anything so there is no simple way (built-in way) to keep threads in sync.

    Currently in PM, you have one main thread which does most of anything and maintains the in-game state. The other threads that run are used to do things that do not really depend on the main thread state (i.e. world generation, runs independently and once a chunk is built is sent as a whole to the main thread).

    In theory it would be possible to make PM more threaded, but it would require a major rewrite (which nobody is willing to do). If I was to make PM more threaded I would do the following:

    1. Split the networking to its own thread.
    2. Each world becomes one thread. So if you have two worlds in your server, you would have two threads, one for each server. The state of each world is maintained in that thread.
    3. Each player becomes one thread. So maintaining the player state is in that thread. You could implement anti-cheat here for example.
    4. Entities could become their own threads. If threads are very lightweight, each entity could be on its own thread, so you could have very extensive AI and still not burden the main server with it.
    Then you would need IPC to communicate between threads, but it would be more "message passing" (not sharing data, which is difficult with PHP thread). For example, the player threads tells the world thread that it is breaking a block.
     
  9. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    If you are to major-rewrite PocketMine for threading, why not just pick a more threading-friendly language like Java...
     
    Legoboy0215 likes this.
  10. MK500

    MK500 Slime

    Messages:
    77
    GitHub:
    markkrueg
    I've often wondered if crop growth could be handled similarly to world generation. Each chunk crop growth would spin off into another thread and then copy the complete set of changes back to that chunk at an interval that could be adjusted in settings.

    I'm sure the complex part is figuring out a good way to handle that communication.

    Water flow could be handled in a similar way. Probably NOT lava or fire because you need to be able to run away from it and interact with it in real time.

    It would appear more "jerky" to the players; but the performance might be much better for massive worlds with huge farms (factions servers).
     
  11. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    Crop growth only takes a very short period to execute. Why need a separate thread?
    Moreover, it is based on random block ticking, which is directly related to ticks. It is usually a bad idea to put code directly synchronized with ticking in a separate thread.
    Moreover, copying the block data every tick will probably spend way more load than you have saved.
     
  12. robske_110 (Tim)

    robske_110 (Tim) Wither Skeleton Poggit Reviewer

    Messages:
    1,342
    GitHub:
    robske110
    Threads don't magically give you infinite power. Only Creating a thread probably alteady takes longer than calculating crop growth. Stuff like anti cheat is making the server busy. (Not really only that though)
    I talked about this with sofe not a long time ago. We came to the conclusion that the time spent to sync and pass block changes entitiy movements, etc. over would take longer than just doing it in the main thread.
     
    Last edited: Nov 25, 2016
  13. aliuly

    aliuly Silverfish

    Messages:
    23
    GitHub:
    alejandroliu
    Depends on how you are splitting the threads. If the two threads require minimal synchronisation, then you get improvements on a multi core server.
    A good example of this would be if you were to split the main thread into multiple threads on a per world basis. (Each world runs on its own thread). Synchronisation between these two threads would be minimal, so both would run at full speed.
     
    SOFe and dktapps like this.
  14. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    And what about world events? Will they still be dispatched on the main thread, or does the plugin have to handle concurrency itself?
     
  15. aliuly

    aliuly Silverfish

    Messages:
    23
    GitHub:
    alejandroliu
    We are just speculating, obviously I am not planing a PocketMine-MP rewrite.

    So each world has its own thread, so world events are handled by that thread. Events that spawn the whole server (across worlds) would need its own way of communication, but in my view, those wouldn't be very common. If we follow the PHP thread model, you would do this through message passing (or equivalent).
     
  16. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    I don't quite get your point.
    If events are handled in world thread, the plugin has to handle the concurrency itself, which is going to be confusing for many developers, and event listeners have to become Threaded, which should not be casually done.
    If all events are handled in main thread, the world thread must wait for main thread to dispatch events, so that is a major killer for performance, isn't it?
     
  17. dktapps

    dktapps Administrator Staff Member PMMP Team

    Messages:
    774
    GitHub:
    dktapps
    Plugins and events are the giant stumbling block to this objective.
     
  18. aliuly

    aliuly Silverfish

    Messages:
    23
    GitHub:
    alejandroliu
    In a "threaded" scenario, I would make a per-world thread, and world events would be handled in that thread. Plugins can be handled in a number of ways. One way is that plugins are created in the main thread or on its own thread, and you would send events as "messages" to the plugin. This of course means that the plugins themselves need to be thread aware.
    Another option would be that you create a plugin instance for each world thread. As long as a plugin doesn't require inter-world synchronization, the existing plugin code would work as is.
     
  19. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    Wouldn't the world spend a lot of time waiting for results from the main thread? This might kill the performance.
    Moreover, sending/getting block changes to/from other threads also consumes performance.
    Then we will happily kick away all the new developers who know little about thread synchronization, since inter-world synchronization is frequently necessary ;)
     
  20. aliuly

    aliuly Silverfish

    Messages:
    23
    GitHub:
    alejandroliu
    As soon as you introduce threading you make things more complex, so that raises the bar on what Plugin developers need to know. On the other hand, a plugin developer can start with easy plugins and grow into the more complex plugins.

    I agree, that's why ideally the plugin specification should tell the server where the plugin should run (i.e. per-world thread, main thread, etc).

    Yes, that is part of the threading overhead. I never wanted to imply that Threading would magically fix all performance problems.

    You can make life easier for new developers if you encapsulate the thread synchronization into some common elements that should work for 80% of use cases.

    That depends on what the plugin does. For example most Mini game plugins are limited to a single world, so inter-world synchronization is not an issue in those types of plugins.

    In my view, per-world thread plugins are those plugins that work heavily with the world environment and/or its state is specific to a single world like mini-games, or the ones that make lots of changes to chunks.

    As a threaded architecture I think you could have:

    The main thread - handles the networking and communication between the different threads.
    1x thread per world for World state. - Manages the world state and sends messages to players/entities in that world.
    1x thread per world for AI - handles the entity AI. This would need to have a synchronized view of the world state thread. This can be done the same way players get their view of the world synchronised. And yes, this adds processing overhead and memory consumption.
    1x thread per player - (optionally), manages the player state, receives network messages from players and decides what should happen. Anti-cheat code would run here.

    Anyway, this is just a suggestion, I am sure the real people in the PocketMine team has good ideas on how this all should work.
     
    SOFe likes this.
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.