I am running linux ubuntu 14.04 LTS in VMware Player (the free personal version). The virtual machine has 6 cores and 4 GB of RAM, with 700 MB of memory dedicated to graphics That should be enough to run Zero-k at 30fps (correct me if I'm wrong). So I have been playing this for about a week now. And my fps constantly drops under 10 fps. Furthermore, sometimes (in large maps or with lots of cai) my fps goes under 3. Making the game almost unplayable (or just annoying). I did some investigation and found that mono is only effectively using 1 core! So I gave permission for mono to run on all 6 cores and restarted the virtual machine. But, still, Zero-k is only running on 1 Core (more specifically core 0)! 1 core has only 1.5 GHz of processing power!!! So is this a mono/linux problem (unlikely because I already played around with the settings), or is this something that spring has to fix, or is this a zero-k problem? Please point me a direction to solve this problem. Please and thank you in advance...
+0 / -0
|
The SpringRTS engine currently mostly only runs on a single thread*. From what I understood a multi threaded version has been in not-very-active development for a few years. If you have a lot of experience with creating multi threaded software I suggest you help out. * quote: currently some of the simulation is multithreaded, some isn't |
- hokomoko's post on Spring forums
+0 / -0
|
1) mono has nothing to do with spring's FPS, it's only used in the lobby. 2) Do other games play in decent FPS on your VM? (playing on a VM sounds like a very bad idea)
+4 / -0
|
First off, why are you running Zero-K in a VM environment? the game has releases on all major desktop platforms, so you'd be better off running it natively. Otherwise, as Skasi said, the engine (or at least the Lua interpreter, which controls game logic) is single-threaded. This is mainly because it is also about 15 years old, and back then multi-threading wasn't even a thing for home computers. Unfortunately the main work on multithreading has been slow going, and one of the approaches involved its developer getting nasty and violating GPL by holding the code hostage, which means the idea has some politics associated with it.
+1 / -0
|
So... the information I have got at this point is: 1. Don't play in a virtual machine 2. Mono has NOTHING to do with spring, mono is just used for the lobby 3. Spring is MOSTLY single threaded because ... 4. Lua is mostly single threaded 5. Spring is open source so I can technically contribute too. 6. I would be wondering into Hostile Territory if I was to try to make a multithreaded lua library. *********************************************************************SideNote: Wikipedia (https://en.wikipedia.org/wiki/Spring_Engine) states that the engine is written in C++. To my knowledge, C++ supports multithreading. Suppose that it is possible to read in all the lua rules of the maps and units in 1 thread. Next, we put all those information in memory. And finally when we are rendering, we could multithreading to help out. I hope my solution makes sense. I can only count myself as amateur programmer because Iv been doing programming for about 3 years (grasping the basics)... Even lua (shadowfury333 implied that it is 15 years old) is older than me :P
+1 / -0
|
Next question... Where exactly is the source code of the spring engine? I went to the following url https://github.com/springAnd I found a lot of stuff ...
+0 / -0
|
https://springrts.com/wiki/Development:Getting_Startedbtw, I'm not sure if MT in drawing is the most significant place for improvement. A significant portion of the limit there is the GPU bus and GL calls which won't run in parallel. Lua can't be made parallel since that means game code has to be sync safe when parallel. (Good luck rewriting all spring games) Most of the synced simulation relies on order, so that can't be made parallel either.
+0 / -0
|
quote: 6. I would be wondering into Hostile Territory if I was to try to make a multithreaded lua library. |
Not exactly hostile territory, just that you are going to be subject to a bit more of a "Show me" attitude than usual. However, since "Show me" is pretty much standard for open source development, it may not even be noticeable. Just be sure to commit the code to the main repository. quote: Even lua (shadowfury333 implied that it is 15 years old) is older than me :P |
I was referring to the Spring engine, not Lua. Lua is, according to Wikipedia, 22 years old. quote: btw, I'm not sure if MT in drawing is the most significant place for improvement. A significant portion of the limit there is the GPU bus and GL calls which won't run in parallel. |
So...port to OpenGL 4.5? :P quote: Most of the synced simulation relies on order, so that can't be made parallel either. |
Does it? Within a single time-step? I'm curious what's being done that doesn't allow parallelization of the physics system.
+0 / -0
|
quote: Does it? Within a single time-step? I'm curious what's being done that doesn't allow parallelization of the physics system. |
A very simplified example (may be slightly incorrect, but the essence should be): Let's take two units dying in the same frame. Both need to leave a wreckage and are competing over a shared pool of ids. If they die in parallel, their ids may get switched leading to desync. Also think about random number generation where order is crucial. These issues may be specifically addressed with some very creative solutions but almost everything that happens in the engine fires up some lua event and if these will run in parallel all hell will break loose.
+1 / -0
|
quote: To my knowledge, C++ supports multithreading. |
Yes. Here's a few things to consider though: If you ever get in touch with parallel programming, you'll notice that every single guide/advice/documentation will tell you that things can and will go horribly wrong unless you know very well what you're doing. Multithreading is difficult to get right, especially in a low-level language like C++. [color=2f2f2f](High level languages have simplified the involved work a lot, but you still need to have a very good understanding not only about what you want to do, how things will work but generally also what is happening under the hood (render threads, thread/object ownership etc.)).[/color] As it so happens (and as said before), the spring engine is basically older than the concept of multithreading for home computers. It's very helpful to build a program in a certain way in order to make it easier to parallelize. spring was not built that way, and while it naturally has been structured into certain components (like any engine) that can be somewhat treated individually, it's certainly not been made with multithreading in mind. As we saw though, it's still possible somehow. Unfortunately, the person who managed to do this refused to share the source code (didn't he also have to change some code inside the executable itself?) for (what I remember being) pretty inane reasons. Another thing you need to understand is that for multiplayer to function properly, every single copy of the engine has to work identically, down to the order in which units die, in which plasma shots hit a target, in which routes units take, collision physics, all that stuff. This is because every client runs its own simulation and only receives the commands players give from the other players (relayed through the host), there's no "master" server to arbitrate any inconsistencies: If the same action has two different results for two clients, they are "desynced" and the game spirals out of synchronisation. A unit that you're giving an order to might already be long dead for the other player, because that one rocket missed another unit that moved in a slightly different path for you than for him. Desync issues are already a (very painful to find, but luckily only very infrequent to be introduced) issue in the single-threaded version. With the added complexity of multithreading, it won't get better.
+1 / -0
|
(new post to break wall of text and respond to something else) quote: These issues may be specifically addressed with some very creative solutions but almost everything that happens in the engine fires up some lua event and if these will run in parallel all hell will break loose |
Are there lua things that need to interact back with the engine (while also affecting relevant stuff) before the next lua callin should happen? Otherwise, collecting and then sequentially processing them may allow that part to be done. I'd imagine such situations would exist, but I can't think of one in ZK right now... quote: If they die in parallel, their ids may get switched leading to desync. |
So basically, all dependence on sequentiality of events would need to be removed. I'd imagine this to be possible by making both the RNG and the distribution of IDs be decided by, say, a hash of relevant arguments (unit id/health/location/reload timer/target id etc.) and the game frame. I get that hashing a bunch of garbage every time you want to assign a unit ID is a lot more time-consuming than incrementing a counter, but I'm not under impression that unit creation is a major bottleneck right now. For RNG you might even find something that behaves well with being seeded every time you call it. We're surely not the only ones with need of reasonable (but deterministic in given parameters) randomness. And yeah, it's easy to suggest something from the outside with no clue how things work (relevant xkcd), but I'm just trying to come up with solutions for presented problems. It's what I like to do.
+1 / -0
|
quote: Are there lua things that need to interact back with the engine (while also affecting relevant stuff) before the next lua callin should happen? Otherwise, collecting and then sequentially processing them may allow that part to be done. I'd imagine such situations would exist, but I can't think of one in ZK right now... |
lua code (1) sets unit position to 0,0,0 lua code (2) gets unit position and sets it to x+10, y+10, z+10 Based on order you'll have the unit in either 0,0,0 or 10,10,10. (don't forget getting can't be scheduled for later) I actually think almost all of ZK's code is prone to desync if it's reordered.
+0 / -0
|
quote: I'd imagine this to be possible by making both the RNG... decided by, say, a hash of relevant arguments |
Even assuming that will work (not entirely sure about that), good luck maintaining that for all synced RNG calls in both the engine and games. quote: And yeah, it's easy to suggest something from the outside with no clue how things work (relevant xkcd), but I'm just trying to come up with solutions for presented problems. It's what I like to do. |
Patches welcome.
+0 / -0
|
quote: (don't forget getting can't be scheduled for later) |
Well it just has to be the same on every client. If all clients collect/delay the lua callins until all units are done (I really have no clue which "phases" the engine goes through for the physics and how it processes entities in there), then process them in order of unit id, it won't matter. You just need to avoid the race condition (yeah, there it is again, the "just", sorry) by making things happen in a defined order when it matters. Yeah, if only it wasn't waaay out of my league (and a massive time investment) :( A good time to thank all the devs, both ZK and engine, for all the man-hours they've sunk into this though! People throwing around ideas (like me) have a hard time grasping how much more it takes to actually formalize and implement them...
+0 / -0
|
quote:
Well it just has to be the same on every client. If all clients collect/delay the lua callins until all units are done (I really have no clue which "phases" the engine goes through for the physics and how it processes entities in there), then call them in order of unit id, it won't matter. You just need to avoid the race condition (yeah, there it is again, the "just", sorry).
|
I'm not even sure what you mean. Callin order is crucial in probably as many as 75% of the lua code. What's even more interesting is that callins may call code that activates other callins. The race condition is only (theoretically) avoidable by changing the entire lua system and the engine considerably leading to: 1) Worse stability - Parallel systems are freakishly complex and now both games and engine devs will need to deal with them constantly. 2) Harder maintenance and development - mostly due to 1. 3) Kittens dying - and we don't want that to happen, do we?
+0 / -0
|
quote: What's even more interesting is that callins may call code that activates other callins. |
That's the thing I was wondering about. Aren't gadget writers either required to pay attention to threadability, or risk killing any threading benefit if they desperately require execution order restrictions though? Hm, gives me something to think about. Well, here's my reasoning: Suppose we have two units dying, each causing a lua callin which will have further impact. The order of the callins is sync-relevant. Making the result of the situation independent from within the lua of the order of the callins seems unreasonable/impossible. Therefore, in the engine, either a) the unit deaths need to happen within the same thread on all clients (since this scenario could be extended to virtually all physics events, this essentially means no multithreading), or b) the order of the lua calls is made independent of the order of the events being processed (what I was talking about with "delaying" the calls). If the result of the lua stuff for the first unit changes what happens to the second unit, the engine might have to redo that calculation (I'm being horribly unspecific, right?) and only then perform the second lua callin. If you imagine this for 100 units killing each other one by one through a chain reaction because of lua stuff happening for each unit death, then it obviously won't really be parallel, but in the same obviousness it never could be anyway. In other words, if it takes 10 sequential communications between engine and lua to properly process a single event, then it'll take that many with multithreading, too, right (again, assuming that lua is to be left out of the parallel business)?
+0 / -0
|
Nope. AFAIK no lua code in spring is multithreaded. quote: In other words, if it takes 10 sequential communications between engine and lua to properly process a single event, then it'll take that many with multithreading, too, right (again, assuming that lua is to be left out of the parallel business)? |
Yes. An example for a thing that can be computed in parallel (and actually is!) is pathfinding. It's well contained, doesn't change outer stuff (the result does, but the process itself doesn't) and doesn't call any lua.
+0 / -0
|
If lua callins results were only applied on the next frame, would that break anything? In other words, anything that touches the game state would not effect other calculations based on current game state. (Two lua calls that need the dead/alive state of a unit would both 'see' it as alive even if one of the calls killed the unit; callins on unit death would only happen next frame) Ie. In such a scheme, a chain reaction of unit dying leading to lua callin leading to unit dying- etc. Would take a minimum of one frame per unit death because each lua code effect on the game state would not take effect until the next frame. I programed a tiny ui, event handler, engine setup because I was curious, and was following such a scheme. Then I found the need to multi thread and realised that my initial scheme greatly helped matters. Going to multi was almost trivial.
+0 / -0
|
So, I guess it would be easier, more efficient, and future-proof to code a multithreaded Spring 2.0 starting from (mostly scratch), than trying to parallelize Spring 1(00) ? This feels relevant to the discussion : quote:
RTSMP (Rethreaded Symmetric Multiprocessing Real-Time Strategy Mutation Platform) :
|
(for Spring games it would seem) http://rtsmp.com/rtsinfo.htmlAlso, this : quote:
Discussion about multithreading (in Homeworld, among other things) and "ballistics" :
| http://forums.gearboxsoftware.com/t/ballistics-in-video-games/143178P.S.: Is that one of the main reasons why Uber went with their central server model with Planetary Annihilation? P.P.S.: http://www.rockpapershotgun.com/2015/08/21/ashes-of-the-singularity-alpha/Ashes of the Singularity (get a benchmark tool for the low low price of $100! one time offer!) seems like it might be the future of massively parallelized RTS games (though I'm suspecting their "revolutionary engine" only really parallelizes display-related things, and not gameplay-related, due to the aforementioned order and sync issues). See also this video : http://www.rockpapershotgun.com/2015/03/08/ashes-of-the-singularity-looks-beautiful-and-expensive/(do you smell bullshit?) Assuming this does work out (I'm not sure it will, but these Oxide guys seem competent enough, and I think I've heard of rumors of Chris Taylor planning a SupCom3, can anyone confirm?), Spring risks to be "left in the dust" once the new generation of large-scale fully-(or at least well-)parallelized RTS makes its appearence. P.P.S.: See also this for the Oxide Engine talk and demo (now free on Steam) : http://store.steampowered.com/app/267130
+2 / -0
|
If someone decides to rewrite Spring 2.0 with multi-threading in mind(where is this super hero?) I would recommend take a look at http://golang.org/It's a programming language with built-in concurrency primitives and green threads which greatly simplifies writing and supporting of multi-threaded code "Do not communicate by sharing memory; instead, share memory by communicating"
+0 / -0
|