BlitzMAX Limitations and Performance

BlitzMax Forums/BlitzMax Programming/BlitzMAX Limitations and Performance

BLaBZ(Posted 2013) [#1]
Hello All -

As my current project is coming to a close I've been beginning to think and plan my next project.

I'm planning to create a large scale warfare engine that can hopefully handle thousands of individual units.

Scalability and performance are huge proponents and I'm contemplating whether BlitzMAX is the best choice.

The alternative would be c++ though I'm not very familiar with it.

What are the limitations of blitzMAX I should be aware of? What language would you suggest I use? Any advice?

Thanks!


Yasha(Posted 2013) [#2]
I would advise against using C++, in pretty much all circumstances (although I won't give reasons, on account of having written so much about this in the past - do a forum search for Yasha/C++ in the unlikely event you care about my opinion).


One of the golden rules in software development is that it is far and away best for you to assume your current tool is fast enough, until you have evidence that it isn't. Programs are faster than you think. People write high-performance scientific data crunchers in Python, and that's interpreted. Video game logic is very rarely particularly demanding or involved, so unless you can prove BlitzMax isn't up to the task, you're basically waving your hands in the air around completely unknown quantities and making decisions based on nothingness - more importantly, potentially crippling your ability to architect and write good code because of pre-emptively switching to a tool that either isn't as clean, or that you aren't comfortable in, just on the off-chance it might be faster (it's actually very difficult to write performant code at a low-level, so the chances are that switching to something like C++ would slow down your code until you master the language several years later).

BlitzMax has several disadvantages, but its average program performance isn't actually likely to be that far below optimising compilers because real-world flexible logic code isn't often all that easy to optimise anyway; for polymorphic OO code it probably generates much the same stuff as GCC would.

When you encounter an area of your code that is too slow (because you profiled it), BlitzMax actually also has one big advantage: it makes it really easy to factor single functions out to C for advanced compilation. When you discover your inner loop that does a lot of matrix manipulation is taking too long playing around with BlitzMax objects, extract the code to a function, rewrite that one function in C with flat structs, and through the magic of BlitzMax's externs system you can actually use the optimised C version in your main program almost completely painlessly. So performance is effectively not a problem because anything that desperately needs optimisation can almost always be factored out by itself.


Future-proofing (e.g. "the 64-bit question", what happens when BRL stop updating the closed-source compiler) and multiplatform support and things like that, are better reasons to consider other tools. Language issues (e.g. weak type system, lack of many modern features, very poor threading support) are another reason to switch, but really only if you know what you want and are explicitly looking for those features somewhere else (simply moving to C++ with its arbitrary collection of junk is not going to help fine-tune your code features, because you'll lose what you need in the crowd).


My overall advice is to learn a language because you actually want to learn a new language - to write different code in a different style, and have it run in different places. As above, looking to languages to get things like performance is a mistake, because you can always find performance escape hatches; and anyway you normally don't need them.

Bear in mind that there are literally tens of thousands of languages out there and most of them are nothing like anything you've ever used. It is a much bigger world than "BASIC vs C++". I always recommend Scheme for something new but not-too-different.


Who was John Galt?(Posted 2013) [#3]
What Yasha said- I'm making a habit of saying that, but he's usually on the money with a well considered response.

Forget C++, it will just add headaches.

I doubt performance will be an issue for the type of game you are considering. Monkey is a decent alternative and I would say is more futureproof. Others can advise what if anything it is missing that Max has, I haven't played with it for a while. The other advantage is that it's almost identical to Max code bar a little bit of boilerplate.


BLaBZ(Posted 2013) [#4]
Fantastic input Yasha!

Do external function calls take just as long as internal function calls?

My biggest concerns are threading and large amounts of matrix operations. I can extract the matrix operations but the threading seems to be the weak point.

For some reason my attempts to utilize more than 2 cores have failed with BlitzMAX, resulting in only 50% use of available cpu(4 cores) power. I've also found debugging threaded operations to be extremely cumbersome and sometimes never figure out what's breaking.

What are BlitzMax's threading weaknesses compared to other languages\frameworks?

Thanks!


BLaBZ(Posted 2013) [#5]
@John - I've developed something similar to this already and performance has become an issue. A lot of the performance issues has to do with the *way* it was coded so in my second attempt I hope to clean this up and it have it very optimized.

Basically, I'm looking to create a game engine similar to "Supreme Commander."

Right now my engine can handle about 200 units, though I would like it to be able to handle at least 2000.


Yasha(Posted 2013) [#6]
Do external function calls take just as long as internal function calls?


They should be the same. Lighter only because whatever happens after the call is lighter (or not, potentially). Both of them will use the lowest-level machine code for a function call.

What are BlitzMax's threading weaknesses compared to other languages\frameworks?


There are two that come to mind:

1) BlitzMax doesn't present any kind of threading or parallelism model. It just gives the user a very low-level API that is the sort of thing you might use to build a threading system, rather than a system in its own right. In other languages you can say things like "launch this in a coroutine", "open a channel between coroutines", "pass objects into the channel", etc.; in BlitzMax you need to actually spawn OS-level threads yourself, manage shared resources with explicit locks, etc. The language runtime has no notion of sharing and cannot protect you from your own mistakes, does not set up any pre-made safe methods, does not even pool threads automatically for you as far as I know (I could be wrong, been years since I looked at this). Languages like Go in contrast use a very safe model where you can divide your work into tasks and share objects by passing them down safe channels between tasks, wait on data to be delivered, never need to think about the number of OS threads vs. virtual threads, etc.

2) Because of the above (lacking any inbuilt concept of safe sharing), BlitzMax's reference counting GC is horribly unsuited to its task, as the refcount updates cannot be handled in a way that is both safe and efficient. (For the record, reference counting is generally a bad/slow way to implement GC anyway, but it works well enough in single-threaded BlitzMax.) This will take a toll on performance, and there may even be subtle bugs (there certainly were when the feature was released).

I could be wrong on both these points, it's been ages since I looked at this.


Who was John Galt?(Posted 2013) [#7]
@John - I've developed something similar to this already and performance has become an issue. A lot of the performance issues has to do with the *way* it was coded so in my second attempt I hope to clean this up and it have it very optimized.
Indeed. The first line of optimisation should be to choose the right methodology/algorithm for the job as this usually gived the biggest performance increases. Trying to optimise the whole thing is a big waste of time, so it makes sense just to identify the slow parts (by measurement) and optimise them.


ziggy(Posted 2013) [#8]
BlitzMax doesn't present any kind of threading or parallelism model.
I did wrote a small TThread class that happens to provide a slightly higher level API for threading operation while threading was being beta tested. Mark got it, modified it a bit, and as far as I know, it's available on the BlitzMax threading module, while it's not documented it happens to work.


GW(Posted 2013) [#9]
Blitzmax is totally up to the task of handling thousands of units.
A few years ago I wrote an RTS engine that handled thousands of units in realtime with tactical pathfinding, 3d line of site and ballistics, all in a single thread and little optimization.
Here is video of the realtime action. The soldiers seem to move slow in the video because this particular map is almost entirely rubble, which hinders movement and makes for terrible line of sight.
You might be able to squeeze a little more juice out a modern processor with c++, but it's not worth the pain imo. Bmax can do the job.


*(Posted 2013) [#10]
I think any programming language that's written right, the only limitation is badly written code ;)


Who was John Galt?(Posted 2013) [#11]
@Blabz.... forgot to mention (and realise this is coming from a 'max fanboy), the only reason I would use anything other than max for a game is if I need external libraries. Then, if there are no pre-existing bindings for max I will not bother. Interfacing can sometimes become more hassle than it is worth.