Godot: GDScript performance improvement via Just-in-time (JIT) compilation

Created on 5 Jun 2016  Â·  105Comments  Â·  Source: godotengine/godot

What about adopting just-in-time (JIT) compilation for GDscripts?

JIT compilation has no disadvantages over interpreted code (aside from slower startup, in some cases) and many advantages, mainly in terms of performance.

For JIT compilation, there are at least two popular ways to implement it in a cross-platform way without writing any code from scratch:

There is also the option of using PyPy, the JVM or the CLR, but those are quite heavier, using GNU Lightning or libjit (not sure if the license is compatible with Godot's) and of course, writing a code generator from scratch (which could take years).

So, the choice is pretty much between LLVM IR and DynASM. Both have very good performance, but DynASM is written in Lua and LLVM has a fairly large footprint (~20MB), but also offers other features.

Of course, compiling GDScript directly to C++ could also be a valid alternative - the only game engine which does it that I know of (if I understood it correctly) is Enigma, which compiles its own scripting language (EDL) to C++.

What do you think about this?

archived discussion feature proposal gdscript

Most helpful comment

I'm working on JIT compilation for my master's thesis and am planning on implementing something suited for Godot. So far I've mostly just read a lot of papers on the topic, specifically on how to deal with the dynamically typed nature of GDScript. I've now started working on a prototype, and hopefully have something to show relatively soonish.

All 105 comments

JIT compilation has no disadvantages over interpreted code

There is one: portability…

But wouldn't implementing static typing be better and easier at least for now? Not to mention C# support which may eventually happen?

@Calinou Portability isn't a big concern, since we could just run the GDScript as we do now on unsupported platforms.

static typing can be optionally jitted too

@Calinou portability isn't a big concern if those libraries are used - they support plenty of architectures (LLVM probably supports more architectures than Godot) and besides, the interpreter could always be used as a fallback (as @bojidar-bg said).

LLVM IR would actually make static typing easier to adopt (on the back-end, of course GDScript would still need either type inference or explicit type signatures).

If C# support is implemented by linking either against Mono or CoreCLR, those both include JITs so this issue will be solved automatically. I can understand why C# (it's a better language than Java and Unity already uses it) but for those purposes, the JVM would probably bring better performance than either Mono or CoreCLR (especially because of the JVM garbage collector, which is well suited for games since it doesn't freeze anything). After Java 8, I personally don't think most people would object to it instead of C# (as the advantages brought by C# at this point mostly come down to Generics and LINQ, both not as useful in game development, which is mostly imperative), and using the JVM gives access to plenty of neater functional languages than C# like Clojure, Scala and Kotlin anyway.

Also LLVM makes it possible to use C++ in a JITted fashion. Unreal Engine also uses C++ for scripting, so I don't think that would be too weird (provided segfaults will be more common, but GDScript could still be offered to less experienced programmers). C++14 (supported by LLVM for the most part) is quite a small language even compared to Java and C#, if used properly (of course, compile times are long and error messages are still not as good).

I would support JIT compiling for GDscript as long as it doesn't mean the end of the language (or its respective built-in editor) as it is now,

My proposal.

  • Add a new static variable type, which in turn can be created by way of doing something like
    static var float(5.5) or something (the core difference would be higher performance and better parsing due to the expectation of it being a specific type. This method should allow the use of static typing while keeping the advantages of dynamic typing and eliminate any need for rewriting scripts if you want to use them
  • After that, add a JIT compiling routine that converts GDscript to C++ behind the scenes (ie. invisible to the user), but visible in the form of performance when the game is run. The idea of using C++ here would mean that the Godot developers would not have to add a bunch of new libraries to the source.

JIT in dynamically typed languages like Lua is done by doing type inference
from the entry point through the call tree, going as deep as possible. I'm
not saying this wouldn't be possible in Godot, as pretty much every entry
point is typed. The code completion in Godot does something similar, which
is why it's able to guess so much type information.

However there are many cases where the type is not obvious, and while the
code completion works great by guessing the get_node() calls on the tree
being edited, this information might be different or change in run-time.
I'm honestly not sure how efficient type inference might be.

To help on this, it would be easy to allow GDScript to allow the user to
"force" the type of a variable (something not possible in lua). But if you
are going to do this, then you might as well just go full static typing.

I'm not convinced of any approach at the moment.

On Sun, Jun 5, 2016 at 5:37 PM, Ace-Dragon [email protected] wrote:

I would support JIT compiling for GDscript as long as it doesn't mean the
end of the language (or its respective built-in editor) as it is now,

My proposal.

  • Add a new _static_ variable type, which in turn can be created by
    way of doing something like
    static var float(5.5) or something (the core difference would be
    higher performance and better parsing due to the expectation of it being a
    specific type. This method should allow the use of static typing while
    keeping the advantages of dynamic typing and eliminate any need for
    rewriting scripts if you want to use them
  • After that, add a JIT compiling routine that converts GDscript to
    C++ behind the scenes (ie. invisible to the user), but visible in the form
    of performance when the game is run. The idea of using C++ here would mean
    that the Godot developers would not have to add a bunch of new libraries to
    the source.

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/5049#issuecomment-223836149,
or mute the thread
https://github.com/notifications/unsubscribe/AF-Z2znHs58L-KDgtIjHYYjgHVUGXgwpks5qIzOngaJpZM4IuWZe
.

Haxe uses type inference even though it is type safe under the hood. Personally I like the fact that I don't have to define the type of every variable but that you can do so if you need it. That way you have the best of both worlds: you don't need to specify types (as long as the compiler can figure them out) and writing "generic"/"template" methods results in a much cleaner syntax as in statically typed languages like C++ or C#, but effectively the code is type safe and you can specify the requested type whenever you want to use it to make the code more readable.

In Haxe it's done using the syntax
var <name> [: <Type>] [=<initial value>]
which looks very weird coming from typed languages but makes perfect sense coming from a language like GDScript.

But I have no idea how this affects complexity and effectiveness of JIT compilation, I merely wanted to point out that this would be kind of a middle ground between dynamic typing as it is now and full static typing as it is in languages like C++.

I used Haxe for 1~2 years long time ago.
I like it to be able to define type optionally for variable and function return as @Warlaan said.

I'd prefer the c++ type declaration style before the typescript/haxe one:

var x = 50
int y = 60
float z =70

Or maybe we could mirror export's style:

type(int) var y = 60
type(float) z =70

@bojidar-bg Personally I prefer c++ style more (a lot less typing).

There are a lot of issues that can arise from putting the type before the variable. Go was written by some of the most experienced C implementers ever (including Ken Thompson) and they went with Postfix notation (like Pascal and Haxe).

I think this discussion belongs in a separate discussion. I'm not proposing a vote because of course most people are used to typed languages like C++, C# and Java and could vote the familiar syntax but merely to gather research materials and opinions to find the solution that is best suited for a language like GDScript (which is clearly not C-like in any other aspect).

I agree in all four aspects:

  1. The C++-syntax is nicer to read, but
  2. imho the postfix notation makes more sense here
  3. which I would prefer to discuss (not decide by majority)
  4. in another thread. Sorry, I didn't mean to hijack the thread when I mentioned the topic. Let's return to the issue of JIT compilation.

Would implementing JIT via LLVM mean Clang would be preffered over GCC . Is it possible to compile LLVM JIT using GCC?

Unlike Java , Python, C# etc, GD Script works as part of a bigger C++ native code engine. In fact both GD Script & the rest of the engine are one unit. Some game components are C++ and some are GD Script. Overall the game performance depends on creating a balance between the two. Writing a Godot game solely in script would make it slower but writing it mostly via nodes with minimal gd script would make it faster.

So my question is . Is this small boost in performance really worth the effort?

I think C# addition may in fact be better for the engine than implementing JIT in GD Script. C# is probably much more optimized and efficient language thus probably as fast as GD Script + JIT but not as integrated as GD Script.

To answer my own question I personally don't see this being an important issue right now. Maybe in the future when Godot has all the desired features and devs would be simply optimizing those features.

Would implementing JIT via LLVM mean Clang would be preffered over GCC . Is it possible to compile LLVM JIT using GCC?

Yes, but then LLVM would become a dependency so it would make more sense to use LLVM for everything.

I don't think the boost in performance would be small for larger games. Maybe for arcade games it would not be noticeable, but in games with a lot of loops and function calls it definitely would.

Also, is there a discussion about why C# over Java or even C++? I think C# is a very good language, but the CLR and tooling is definitely inferior to the JVM (especially on other platforms than Windows).

@paper-pauper you should make a forum post about Java, JIT to continue this discussion. I'd actually prefer Java > C# tbh. I think C# was a not a choice but more of an opportunity that devs decided to take.

so that in the end we decided? will JIT or not?

How about the ability to compile GDScript to static C++ code? Would that even be possible?

@trollworkout : it would probably be simpler and more optimized to write your game logic directly in C++ then, wouldn't it ?

@SuperUserNameMan Not necessarily. First you would be using C++ not GDScript and second you still need to figure out a way to load a binary object as a dll and plug it into the engine without having to recompile the engine with ur C++ changes.

@trollworkout Thanks to #3936 it could be possible to compile GDScript to C and load it dynamically, eventually.

it is not necessary to translate the script in c ++. @SuperUserNameMan rights

or need JIT or c# and all will be happy

nah the other topic @paper-pauper linked is actually much more interesting. The idea is to use C binary as a type of scripting language and call code directly via reflection rather than being interpreted making it as fast as C++ native code I think that would solve the ABI issue . In fact with this you don't need ABI anymore.

I am currently experimenting with implementing a GDScript JIT using RPython. The first (very preliminary) results are promising, but I don't know how hard it will be to integrate it into the engine.

Is there still interest in a JITed GDScript or are people more interesting in c# or static GDScript?

Considering that you're actually trying out a possible solution, I say go for it and see if there's enough performance gain in games to be worth it.

What I mean by that is such a thing would only be worth pursuing if there's a rather large performance gain to be had for complex logic (or otherwise such gains might be better obtained from just doing general optimization work on the language itself).

Performance is crucial for me, I just can't choose Godot for the script
Performance. But I think a faster language(Lua, Java, c#) is better than Jit, since Jit doesn't work on iOS. And compiling to c++ loses the possibility to update game logic on iOS

Isn't Lua faster just because of JIT? Or does it have some kind of AOT compilation too?

I still prefer a statically typed GDScript (maybe an optional typing system, like TypeScript is for JavaScript). Also having GDScript -> C++ transpilation would solve a lot of performance issues, but I can see this is far from trivial.

How do you update the game logic in ios? you can't download scripts from
your games and run them on ios, everything has to be installed from your
original ipa that is published in the app store. Either way you have to
update the app to get new logic, event if it's new scripts or a new runtime
with the logic compiled in.

On 20 August 2016 at 05:05, George Marques [email protected] wrote:

Isn't Lua faster just because of JIT? Or does it have some kind of AOT
compilation too?

I still prefer a statically typed GDScript (maybe an optional typing
system, like TypeScript is for JavaScript). Also having GDScript -> C++
transpilation would solve a lot of performance issues, but I can see this
is far from trivial.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/5049#issuecomment-241175124,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AGVmPZDOcIkO1-6ayDySyPnCfJdRk5Saks5qhm76gaJpZM4IuWZe
.

Statically typed GDScript with optimized VM would be also be good, is there any plan for this ?

Optional typing system for GDScript as @vnen suggested would be perfect :)

While researching about this, I've found the great SLJIT. I have been trying to figure out how could I integrate it to allow JIT compilation at least at the GDScript function level.

After some hours of reading/thinking I've come to the conclusion that it would be of little benefit because the biggest bottle neck, now I have studied the code deeplly, is probably all the Variant stuff.

Finishing my task for a test would be overkill so I've abandoned it. Anyway a branch with my initial work is in my repository in case someone wishes to play with SLJIT and have it already integrated into the build system.

So I sum myself to the group that believes that static typing would remove a lot of calling and branching thus improving performance notably.

@RandomShaper

I agree that the JIT is not feasible currently, but the problem is Variant and not dynamic typing.

I've experimented with writing GDScript JIT using RPython, which is the base for PyPy and specifically made to create JITs for dynamic languages.

I disagree that the problem is static typing, it would be possible to have a fast GDScript JIT if we wouldn't have to work with Variant. Variant does replicate some of the functionality of dynamic languages, and unfortunately that is the part where RPython's JIT gets its speed boost. RPython needs to know what types it currently has and can then speed up those parts.

Variant is so deeply embedded into Godot however, that it's really hard to go without it. I would have to basically reimplement all of GDScripts data types and transform to Variants afterwards.

If anybody has an idea how we can get by without using Variants, a fast GDScript would be possible (a proof of concept GDScript JIT of mine that didn't use Variant was promising. A (silly) loop that in GDscript took 20 seconds was done in under a second when JITted)

Well, I was treating Variant and dynamic typing as if both were the same
thing or as if one couldn't be without the other.

But probably I'm missing something on language design.

AIUI Variant make possible to use C++ in Godot as if it were a dynamically typed language. Especially in the return type for some methods. I'm not that acquainted with the source, but I'm not sure if there's a clean way around it.

@brakhane Care to share your RPython experiment? I think everybody here would benefit from taking a look at it :smile:

Variant is so deeply embedded into Godot however, that it's really hard to go without it. I would have to basically reimplement all of GDScripts data types and transform to Variants afterwards.

In theory, what would be the drawback to this (aside from the time needed to implement it)? This kind of casting is not that expensive, as far as I understand it.

@paper-pauper look at PyPy and RPython - Python is strictly dynamically typed, and PyPy can speed-up Python code very well thought... RPython is very good for development of interpreters (with almost-free JIT)

A really interesting article has been published about (currently in development) new Ruby JIT.

The key part here is the Ruby choose to implement their JIT by generating C code and calling an external C compiler to build a .so then load it. Needless to say this has created a lot of interrogations and this article starts to give some answers.

Basically the advantage to use and external compiler (as opposed to integrate a JIT framework) are:

  • independence to a single compiler (can use GCC or LLVM depending on what's available/best)
  • JIT frameworks like libGCCJit are young so their API can be much more fragile that C

Of course this needs to be taken with a lot of precautions (the article benchmarks compare a prototype with production ready projects such as JRuby), but it shows that, provided you use clever optimizations such as precompiled headers, using an external compiler can be a viable solution.

From the Godot point of view, this technique could be useful to also provide a static compilation of GDscript.

I'm working on JIT compilation for my master's thesis and am planning on implementing something suited for Godot. So far I've mostly just read a lot of papers on the topic, specifically on how to deal with the dynamically typed nature of GDScript. I've now started working on a prototype, and hopefully have something to show relatively soonish.

@DoctorAlpaca I'm almost done with the static type checks for GDScript, I believe this might help you at least a bit (you can look my fork if you're interested, and also #10630). I was planning to look into JIT eventually, but I have zero experience with it.

Some time ago I started an experiment about JIT-ting GDScript. I did setup some foudation for it.
In case you want to have a look... https://github.com/RandomShaper/godot/tree/exp-gdscript-jit-master

@vnen I'm actually very excited to see how much of a difference in performance static typing can bring, as opposed to the type profiling I'm planning on doing. Since I'll also have to produce some actual text for my master's, I don't think I'll get much more done than a prototype, on which there'll be a lot of room for improvement.

@RandomShaper That setup looks nice, and after looking at the available options I'll probably go with SLJIT as well. Thanks for that!

May 2018 poll results have arrived, and this proposition appeared to be on the roadmap priority.

I personally don't think JIT GDScript would be good idea:

  • JIT is not allowed on mobile platforms (at least on IOS, not sure about Android), which are the one needing the most this kind of optimisation...
  • JIT is a big mess. There is multiple approaches (tracing vs method JIT), some of them not even deterministic :'-(
  • JIT is a BIG BIG mess. Debugging is complex (involving dumps of jited code and memory...), so is profiling, so is maintaining the code :'-(
  • JIT is a special kind of mess. JIT programmers is a scarce resource so maintaining such a thing would be tricky. This could lead to making GDScript evolve becoming harder since the interpreter and the JIT would be tightly coupled.

The luaJIT project illustrate well those points: the project is simply brilliant (code base really good, performances crazy good), it solve a real usecase, it is used by commercial companies.
And yet it is slowly dying since it main author has step back, unable to keep up with the new lua version (luaJIT stopped at 5.1, arguing the add of integer on top of float in the language made by the 5.2 would be really complex to add), even if the lua community has a medium size and luaJIT it best known project.

Obviously GDScript is order of magnitude simpler than Python or even lua, but the burden of making a JIT stays an important one, especially considering it is not a core feature of the Godot project.

The only acceptable solution here would be to rely on llvm which would take care of all the crazy parts and let us just output llvm-ir code to it. However, as said before, llvm is a big dependency (at this point we could almost ship v8 with Godot and write a GDScript to Javascript transpiler instead :trollface: ), so additional research to understand how much would be added is required here before going anywhere. And again this wouldn't be a viable solution for at least IOS platform (damn you Apple !).

I'm sorry to sound so gloomy here, but I wouldn't post this without a proposition ;-)
I guess what poll voters understand by "JIT GDScript" is "GDScript, but fast as native code". So in the end it doesn't really matter what it the mean to reach this goal right (AOT, JIT, transpiling + compilation etc.) ?

From what I saw of GDScript, a really cool (lack of) feature is it is not a dynamic language. There is no exec keyword, no monkey patching, you cannot modify variable during debugging etc.
This makes the language suitable for static compilation (and in fact it is again one more reason not to go with JIT). On top of that the new static typing system should allow easy optimisation (compare to having to do type inference).

So my idea would be to start by making a simple (no optimisations, just use Variant everywhere) GDScript-to-C transpiler, that would available as godot --gdcc <myfile.gd>. Using the existing GDScript compiler and GDNative api should make this relatively easy.
The users are then left to deal with the rest of the toolchain (for example compiling each C file as a .so and replace the original .gd file by a .gdns file pointing on the .so).

In a second time, we could start wondering about optimizations and, more importantly, a way to ship a compiler into the Godot.
Considering this second point, tinycc seems a really interesting solution given it low weight, it number of platforms supported (x86, amd64, arm, arm64 for linux, win32 and osx), it libtcc.h api that allow to integrate it into a program and it cross compilation mode. On top of that version 0.9.27 has been released last December (so the project seems stile alive ^^).

Finally the same way we currently turn .gd files into .gdc or .gde at export time, we could create a new type (.gdso ?) that would be nothing but a regular nativescript (so the GDNative resource loader would call Nativescript on it automatically).

I agree it would be overkill to write a JIT compiler for GDScript. As you mention, JIT compilation is not allowed on iOS (Android does allow it), so you would either have to fallback to the slow interpreted on that platform or write an AOT compiler (look! now you have to maintain two compilers as well as the interpreter).

I said many times that I consider the GDScript2C transpiler to be the best option now that we have GDNative.

For binaries built with the mono module, you could write a GDScript2IL compiler and then you would have both JIT and AOT compilation.

From what I saw of GDScript, a really cool (lack of) feature is it is not a dynamic language. There is no exec keyword, no monkey patching, you cannot modify variable during debugging etc.
This makes the language suitable for static compilation (and in fact it is again one more reason not to go with JIT).

Actually, in GDScript you can modify the source code for a script at runtime.

Actually, in GDScript you can modify the source code for a script at runtime.

@neikeq I looked for this before writting my post, guess I didn't look close enough ^^
can you point me to an example ? (or where it is implemented in the codebase)

Actually, in GDScript you can modify the source code for a script at runtime.

Not as much as "modify". You can set the source_code property of Script with a whole new code and then call reload() to recompile it. Technically this is implemented for C# as well, since it's part of the Script API.

@touilleMan your idea is similar to what's discussed in #11068.

Problem with transpiling GDScript, or compiling it ahead of time, is that even with the static type system all method calls still have to be virtual. Anything could hide behind a Node parameter. So you'd run into similar performance problems as Java, which uses JIT on its bytecode for (in part) the same reasons.

In any case, since I need a practical part for my master's thesis I'm going to implement a JIT for GDScript anyway, so after that we can see how well it fares and how much it destroys the code base. I honestly wouldn't mind even if it stays a prototype forever and never gets merged.

Also, for the dynamic things, you can load script files from anywhere on the disk and use them for anything you can use scripts in your project for. Which is a very nice feature for DLC and/or user created content (though I don't know if anyone is actually using it).

@vnen The source code in C# is only used for scripting. It's not compiled on reload.

@touilleMan

Considering this second point, tinycc seems a really interesting solution given it low weight, it number of platforms supported (x86, amd64, arm, arm64 for linux, win32 and osx), it libtcc.h api that allow to integrate it into a program and it cross compilation mode. On top of that version 0.9.27 has been released last December (so the project seems stile alive ^^).

Bad idea, the project is more likely dead than alive!

@neikeq

For binaries built with the mono module, you could write a GDScript2IL compiler and then you would have both JIT and AOT compilation.

But this is an interesting option. And perhaps comparable to the labor costs with the addition of JIT.

In general, if there is already a person who will be engaged in this in any case, then let him do it. The team does not lose from this. I propose to relax and wait, suddenly something will turn out (although I do not count on it)

@DoctorAlpaca considering the virtual method dispatching, I guess things are already this way when using the C++ API. So your goal here is to make GDScript faster than C++ ? ;-)
Anyway, I'm sorry if my previous post had appeared to you in a "it's useless, you shouldn't do it" style.
Experience is immensely more valuable than supposition so I can only support you no this, on top of that there is great chances your work will bring you to improve various part of the engine (bug fixing, cleaning, or even finding optimizations for the too-dynamic-to-be-fast Variant system) so nothing is never lost !
BTW if you're really interested in JIT, I suggest you come to the Europython (end of July in Edinburgh, I'll be there ^^), the Pypy team is there every year and you can do sprint coding on Pypy with them during the whole weekend. There is usually not much people and they are really kind and pedagogic so it's basically like taking a 2 days class on JIT with world class experts ;-)

@ret80 I agree the tinycc project is not really active. On the other hand we are talking about a C compiler, the most used standard is still C99 (with C89 still really present) so there is not much evolutions to do once the project is stable enough (I guess we could say evolutions could be done in optimization, but this would likely add to the size and the speed of the compiler, so not the goal of this project).
My biggest concern for this compiler is more the support of arm architectures and cross compiling .dll and .dynlib because they are more exotic feature (so potentially less tested).
Finally given we would use this compiler with autogenerated code (always same constructions and gdnative as single dependency), we should be relatively safe not to hit hidden bugs once the project is on track.

@neikeq I find really elegant the idea of using the mono runtime for the JIT ! This would keep low the number of dependencies (and improve the number of people involved in the mono module which is always better) and they would save us from making yet another release.

Honestly I would not JIT but rather AOT compile. Something like TerraLang (a lua frontend to LLVM designed to dynamically build languages) would be useful for both development hot-reloading of source as well as compilation out to binary native objects for compilation linking (no interpretation, pure LLVM compiled) would be useful as it would be fairly trivial to specialize for even specific Node types. Virtual overhead would likely still be an issue but it would be a great deal faster than how it is now, especially once typing information starts to exist. Personally I'd just embed LLVM into the editor/compiler, yes it would increase the size but it also means that games themselves could end up even smaller, especially if you include the object files and/or source of godot with the editor and let it LTO it all into a smaller and faster final output.

The luaJIT project illustrate well those points: the project is simply brilliant (code base really good, performances crazy good), it solve a real usecase, it is used by commercial companies.
And yet it is slowly dying since it main author has step back, unable to keep up with the new lua version (luaJIT stopped at 5.1, arguing the add of integer on top of float in the language made by the 5.2 would be really complex to add), even if the lua community has a medium size and luaJIT it best known project.

I'm not sure I would call it dead, it was forked on github a long while ago and is being updated to modern LUA versions and so forth.

I find really elegant the idea of using the mono runtime for the JIT ! This would keep low the number of dependencies (and improve the number of people involved in the mono module which is always better) and they would save us from making yet another release.

Still not allowed on iOS and so forth though.

I still think JIT idea should be merged with GDNative somehow so that GD Script gets pre-compiled a kind of 3rd party C opcode and GDNative should be able to parse this opcode and translated into C++ code.

@OvermindDL1 thanks a lot for mentioning TerraLang, it seems like a really interesting project ;-)

I'm not sure I would call it dead, it was forked on github a long while ago and is being updated to modern LUA versions and so forth.

I'm not really close to the lua community so my understanding can be wrong on this topic. Can you point me to the forked version of luaJIT implementing the new lua versions ?

@OvermindDL1 thanks a lot for mentioning TerraLang, it seems like a really interesting project ;-)

They are very PR friendly, it's a really nice project that just isn't really noticed by many as of yet. It is quite nice to whip up a language inside, built in parsers, LLVM integration, can output fully compiled and optimized binaries, etc...

Even considering that, if I were to write a native backend compiler for GDScript, I'd probably just use the latest version of LLVM's C++ API. The C API is stable, but the C++ API just has so much more power, a lot of power that is needed for implementing a language and not just scanning, especially if you want to use libclang for the full optimization suite. However, TerraLang is entirely functional in that way as well and is significantly easier to use if less well tested and using an older LLVM version (C++ API, though they want to update, so of course PR's welcome).

I'm not really close to the lua community so my understanding can be wrong on this topic. Can you point me to the forked version of luaJIT implementing the new lua versions ?

I ran across a couple of interesting ones at https://github.com/LuaJIT/LuaJIT/network at one point, it's been forked so many times and there is so much development work happening on it on a few big forks. I'm not really big in the Lua community either, I implement luajit in a few projects to get scripting support but don't really write lua myself (apparently lua has a package manager nowadays, luarocks or something). I've run across a big fork or two of luajit that is not directly forked from the luajit repo as well (so will not appear on that list), and I 'think' the biggest I saw was not listed on that list...

I admit that I kinda lost track of all the stuff people propose here, but there seem at least some that say GDScript needs to become statically typed or the JIT should be based on LLVM. I strongly disagree with these statements.

Recently I started working on JIT for GDScript by using RPython (the toolkit PyPy uses to create their JIT), and I've looked into using LLVM as an alternative also.

To make a long story short: LLVM is not suitable for JIT, I've read quite a few blog posts coming to that conclusion, and my experiements with it also seem to confirm it. There are two main reasons:

  1. LLVM is slow. I do not mean the code generated by LLVM, I mean the time it takes for LLVM to create that code creates a bottleneck for a JIT. Webkit's JIT switched from a LLVM to a homebrew solution, and that was one of the reasons

  2. LLVM assumes your code is statically typed, and is just a bad fit for compiling dynamically typed languages.

This is why I have given up on LLVM (which is a shame, because I really like it), and am working with RPython. It has pros and cons:

The pros

  1. RPython is a perfect fit: It is a system to build JITted interpreters for dynamically typed languages. Alongside Python(PyPy), people have written PHP interpreters that turned out to be much faster than the official one, Ruby, and custom languages.

  2. RPython is a great system to build tracing JITs for dynamically typed languages. For dynamically typed languages a tracing JIT seems to be the best solution. Implementing a tracing JIT is hard work and requires to add measuring points to non jitted code. RPython now exists for over 10 years, has very intelligent people working on it (and a few academic papers have been released about RPython), and it requires you to do very little to get a running JIT. Basically, it expects you to write a bytecode interpreter in RPython and tell it which bytecodes are jump instructions and it does the rest (and does it quite well, too; early experiments suggest a speedup of 40x for computation heavy code might be possible)

  3. The JITted code is quite fast, and it supports x86, x64 and ARM backends

  4. It is an active project with quite a few people working on it and an active community.

  5. The bytecode interpreter and functions are quite readable. The current implementation in Variant_op.cpp looks horrible; don't get me wrong, I know why it looks that way and that it's necessary for good performance, but hacking on it isn't much fun.

The cons

  1. (Parts of) Variant.cpp need to be rewritten/duplicated in RPython.

GDScript's solution of dynamic typing, the Variant class, makes it hard to create good JITTed code. One of the things the JIT pipeline does is noticing when a function is often called with an int parameter, for example, and then optimizes for this case. If we would just use Variant as opaque types, tests suggest we can only get a 2x speed improvement, because all we end up effectively is compiling GDScript into C++ code that effectively calls Variant for every single operation, like adding or substracting.

Therefore, to get actual use out of the JIT, at least some parts of Variant have to be duplicated as RPython code so the JIT knows whats going on. It isn't very pretty, but seems to work.

  1. RPython creates C code, not C++. Kinda unfortunate, but we can make it work, especially with the GDNative interface

  2. We have code written in two languages, C++ and RPython. However, Godot already uses SCons, which is Python, so strictly speaking we're not adding a new language

  3. RPython is not fun to program in. Basically you end up writing in a language that's somewhat more powerful than C, but not as powerful as C++, and it takes some getting used to what Python constructs you can use and which you can't

  4. The translation process to turn the RPython code into C (which will be the fully working JIT) takes ages, and I'm not exaggerating. In this early stage of development, it "only" takes 1-2 minutes, but I'm expecting it to take 20-40m for the somewhat complete implementation. This isn't as horrible as it seems however, because the C code would only needed to be generated when the JIT is modified itself, otherwise, the Godot compilation process can just use the generated C files.

I'm hoping to get a PoC working in 4-8 weeks for more feedback.

@baekdahl Too much reading. GDScript is going to become typed regardless of what you think. The decision came from the very top and is gonna happen in the near future.

@CarlGustavAlbertDwarfsteinYung GDScript is becoming optionally typed. Big difference for this problem.

To make a long story short: LLVM is not suitable for JIT, I've read quite a few blog posts coming to that conclusion, and my experiements with it also seem to confirm it. There are two main reasons:

That's because the JIT should be at dev time. When making a release then a full static native compilation should happen. LLVM may not be the fastest JIT, but it is a JIT while also being able to fully native compile to standalone libraries/objects/programs.

LLVM assumes your code is statically typed, and is just a bad fit for compiling dynamically typed languages.

Mmm, actually it has some quite fantastic dynamically typed interfaces.

Regardless, if GDScript is becoming typed then that's not an issue anyway, the 'dynamic' parts of GDScript would just become a variant anyway.

This is why I have given up on LLVM (which is a shame, because I really like it), and am working with RPython. It has pros and cons:

@brakhane Is it capable of native compilation? If it is not then it seems like a non-starter as you cannot JIT on platforms like iOS, in addition that a JIT at runtime will slow loading and spool-up where AOT has no such cost upon releases.

GDScript is becoming optionally typed. Big difference for this problem.

Yes, but even the 'untyped' parts are variants, which is rather trivial to represent in LLVM.

That's because the JIT should be at dev time.

Then it is not JIT, but normal ahead-of-time compilation.

Is it capable of native compilation? If it is not then it seems like a non-starter as you cannot JIT on platforms like iOS, in addition that a JIT at runtime will slow loading and spool-up where AOT has no such cost upon releases.

No, it's a JIT. And if iOS doesn't allow JITs, it's not going to work there. 🤷

Yes, but even the 'untyped' parts are variants, which is rather trivial to represent in LLVM.

But you don't get that much speed improvement out of it, as I mentioned.

It is rather easy to compile GDScript like this:

while i<10:
    foo(i)
    i = i + 1

to something equivalent to the following C++

// i, foo are Variant
while (i.op("<", Variant_10_const)) {
    foo.call(i);
    i = i.op("+", i, Variant_1_const);
}

(or something like that, don't remember the exact Variant API, it's been some time)

But this will only get you around a 2 times improvement in speed. Turning it into a while (i<10) {foo.call(new Variant(i)));i += 1} is much more difficult to achieve.

Mmm, actually it has some quite fantastic dynamically typed interfaces.

I'd love to hear about those.

Then it is not JIT, but normal ahead-of-time compilation.

A JIT may not produce quite as fast of code in general as AOT, but it is much faster turn-around time during development so it is still useful there. However I'd be quite good with AOT even at dev time since if the individual modules are compiled separately then it is not much of a speed issue regardless (<1s easy).

No, it's a JIT. And if iOS doesn't allow JITs, it's not going to work there.

Ah yeah that would not be useful then. iOS requires either a full slow interpreter, or it requires AOT. In addition AOT loads faster, requires a smaller runtime, can perform LTO, etc...

But you don't get that much speed improvement out of it, as I mentioned.

Except Typed GDScript will be able to infer 'most' types regardless (it could even be able to decorate the variant on the get_node calls to create a happy path for the expected node type based on the scene with standard variant fallback). However, in the great majority of cases, even in non-typed code, it will still be able to infer the great majority of types, thus gaining significant performance enhancements and generated code reduction.

(or something like that, don't remember the exact Variant API, it's been some time)

Eh, that is not even remotely how I would suggest doing it honestly. Performing a native < operation via a visitor would be significantly more performant than string testing as just one example. However I'm not sure this example is very valid as I'd imagine that the type of i would be inferred as integer up above where it is set (unshown code) and even if it is not then there could be a single type check before the loop to check if it works with such integral comparisons and if it does not then throw an exception or error in some other way, otherwise acquire the integral/float value out of the variant (likely cast to something useful to minimize code gen, LLVM already has passes to optimize this though) and the loop would then become fully optimized regarldess. You want to minimize variant time entirely and make checks for it's access early and often. Falling back to visitors is not that slow either especially since the majority of the visitor would just throw an error (like calling a method on an integer).

But this will only get you around a 2 times improvement in speed. Turning it into a while (i<10) {foo.call(new Variant(i)));i += 1} is much more difficult to achieve.

This seems pretty trivially optimizable though? Everything would be quite native right down to calling a trampoline for foo to dispatch appropriately or so (simple wrapper function to perform the untyped to type dispatch-or-error), but even then if the type of foo is known (possible also inferrable if not explicitly typed) then that would be optimized out as well.

I'd love to hear about those.

Other than inline native-code-generating JIT that LLVM itself has (which would work perfectly with all the above and would be fantastic for dev time edit-code-while-running while still able to do AOT for Releases) that allows for a direct JIT translation, there are also libraries such as pyston, fastlua, among others built on LLVM that have various forms of tracing JIT's for on-demand improvement, which I personally find fairly useless for dev time and you can't use at a reliable Release time anyway because of platforms like iOS, so I don't see the point.

@OvermindDL1 You are still talking about AOT that gets automatically triggered when saving an edited GDScript.

And yes, if GDScript gets optional static typing, those parts where types are enforced can be converted into pretty effective machine code. GDScript is also pretty limited with what it can do, so I don't think even making it strictly static everywhere wouldn't be that much of a loss.

And if people want to implement such a thing, they can. I have already written some static compilers and that problem isn't interesting for me.

What's interesting to me is creating a JIT for a dynamically typed GDScript that runs on PCs. It would be nice if other people would end up using it too, but it's not a requirement for me. I appreciate the "you might be wasting your time" warning though.

Eh, that is not even remotely how I would suggest doing it honestly. Performing a native < operation via a visitor would be significantly more performant than string testing as just one example.

IIRC, it's not really a "<" but more of a Operation.LT parameter that's given.

This seems pretty trivially optimizable though?

It isn't though, unless you want to reimplement a complete new GDScript interpreter. And even then, you will have a hard time inferring types except for trivial cases.

If you simply want to replace the opcode interpreter part, it's not as trivial (fun fact: the ".gdc" files are not bytecode, but more like the tokenized source code that gets interpreted and turned into in-memory bytecode later). At this point in time, you know the following:

  • There's a variable i, which gets compared ("less than") to another variant whose contents are opaque (although you could use the internal API to see it's an integer with value 10)
  • There's another variable "foo", which gets called with i as the parameter
  • i gets assigned a new value, the result of adding i to another opaque variant

If you want to be able to do AOT compilation, you basically have to reimplement the whole GDScript interpreter. Which is not as trivial as it sounds, as a significant part of the interpreter is part of the Variant class. And Variant is what holds godot together, even the parts that are not GDScript heavily rely on Variant. So when you start messing with it, you suddenly are risking breaking backwards compability for the GDNative interface.

It really isn't as easy as it sounds at first; I was also surprised when I first dived into it.

You are still talking about AOT that gets automatically triggered when saving an edited GDScript.

Not everywhere, rather only on Export. Now I would prefer if it was AOT on save but it doesn't have to be, you could just AOT on Release/Export and JIT when running it via the editor or so to allow for hot-swapping of code during runtime.

And yes, if GDScript gets optional static typing, those parts where types are enforced can be converted into pretty effective machine code. GDScript is also pretty limited with what it can do, so I don't think even making it strictly static everywhere wouldn't be that much of a loss.

Based on the current spec there is a lot of inference, 'most' code should in general by automatically typed by inference. I'm quite excited about that. (I'm a fan of HM typing, have implemented it a dozen times in a variety of ways over the years!)

What's interesting to me is creating a JIT for a dynamically typed GDScript that runs on PCs. It would be nice if other people would end up using it too, but it's not a requirement for me. I appreciate the "you might be wasting your time" warning though.

Yeah a JIT absolutely should not be mandatory as that means it would not be exportable to all supported platforms (in addition to adding overhead). AOT or interpretation should always be the primary method, and considering that most platforms that don't support JIT (iOS, webassembly, etc...) also tend to be the platforms that are the least efficient, then AOT should absolutely be the default, not interpretation, which is even better since typing is being added.

It isn't though, unless you want to reimplement a complete new GDScript interpreter. And even then, you will have a hard time inferring types except for trivial cases.

I'm not talking about for interpretation, I'm talking about for compilation. If entirely untypeable code gets compiled then it would just become variants in machine code (tagged sum type), and any access of it, like say an operator< function would just perform a vistor call on that, which involves a single static jump based on the dynamic type value, then execution of the static code (which if it is, say, an integer is inlined, if it is, say, a custom type then that would likely end up performing a virtual call, or even a static call if it is a large type implemented directly in the variant like a vector).

If you simply want to replace the opcode interpreter part, it's not as trivial (fun fact: the ".gdc" files are not bytecode, but more like the tokenized source code that gets interpreted and turned into in-memory bytecode later).

Not at all, opcodes should not exist whatsoever by the time that AOT is complete, it should be pure machine code lowered to at the largest of variant dispatches on machine code or to the smallest of perfectly known and typed efficient machine code.

There's a variable i, which gets compared ("less than") to another variant whose contents are opaque (although you could use the internal API to see it's an integer with value 10)

If the variable i's type is known then you can generate machine code that tests the type of the opaque variant and if it is not an immediate compatible match then immediately error, else then perform the comparison based on the i type. If the variable i's type is not known then it will be a full visitor dispatch on the two variants (a statically known function call) to acquire the type tags of the variants and jump to the appropriate machine code for the given types.

There's another variable "foo", which gets called with i as the parameter

If the call type of foo is known, as an example in ML notation, int -> int, then if i's type is also known and is also an int then perform efficient machine code, if i's type is not known then test the type tag if it matches, if it does not then error, if it does then extract the value and perform efficient machine code. If the call type of foo is not known but the type tag states it is callable (else error) then if i's type is known (for all definitions of known here I mean both known at compile-time and is consequently unboxed) then wrap it in a variant (efficient inline setting of the proper type tag and placing i's bits into the proper bits) and perform a variant call to the wrapped trampoline function, which then verifies the arguments and calls the actual internal function (which would have been called directly if foo's call type was statically known).

i gets assigned a new value, the result of adding i to another opaque variant

All relies on what the known static type of i is now, and perform the appropriate above described native code generation as necessary.

If you want to be able to do AOT compilation, you basically have to reimplement the whole GDScript interpreter.

Which is still less work than creating a JIT specifically for GDScript unless you are wrapping an existing JIT (of which it's expected operations may not match GDScript perfectly). AOT generation itself is not much more difficult than creating an interpretor, especially on LLVM as it does the significantly hard work for you (optimizations, LTO, machine code generation, debugger, etc... etc...).

Which is not as trivial as it sounds, as a significant part of the interpreter is part of the Variant class.

But still not as hard as implied (I've written quite a variety of languages over the decades, many down to machine code, both directly to x86 and via LLVM).

And Variant is what holds godot together, even the parts that are not GDScript heavily rely on Variant. So when you start messing with it, you suddenly are risking breaking backwards compability for the GDNative interface.

Which is precisely why variants should be baked straight into the machine code. No opcode interpreter or anything of the sort, instead do full and proper visitor dispatching (whether via a local jump based on the type tag or even via a longcall from a static array (dispatch table)). This would not only keeps backwards compatibility but also allows for the GDNative interface to then directly load the fully AOT compiled libraries (or if Godot gets the ability to LTO the engine to the GDNative interfaces via binary objects then LTO optimizations could be applied, which could then signficiantly reduce the output size of the final program as then known unused code could be removed, though that would be a later task).

It really isn't as easy as it sounds at first; I was also surprised when I first dived into it.

It's certainly a non-trivial amount of work, and in fact most of it is a large amount of busy work to translate the previous GDScript compilation pipeline to generate LLVM Assembler Code (of which it has a fantastic API to do so though) instead of opcodes. But it is entirely doable, and in not quite as long a time as one might expect given a language implementation.

BTW, all Variant operators are treated in here: https://github.com/godotengine/godot/blob/d2b75557a5dedf951ee036ca01af4f94bc059069/core/variant_op.cpp#L391-L392

Which is quite optimized already.

BTW, all Variant operators are treated in here:

Ah cool, so it's already using a computer goto, could just use that then (although would probably want to toss that into LLVM as well so it can inline known call paths when possible, but yep, exactly something like this, this is very much a variant visitor and would be used in the worst case of when no types are known at all. Though if anything is known about the types then it would be even faster to do more directly optimized calls, and of course if all types are known or there is only a single valid branch then optimized non-variant machine code can be generated (either via extracting the data from the variant (more likely passing in the casted bit section) or just using the data already in registers/stack/heap if local or already extracted).

But you don't get that much speed improvement out of it, as I mentioned.

It is rather easy to compile GDScript like this:

while i<10:
foo(i)
i = i + 1

to something equivalent to the following C++

// i, foo are Variant
while (i.op("<", Variant_10_const)) {
foo.call(i);
i = i.op("+", i, Variant_1_const);
}

(or something like that, don't remember the exact Variant API, it's been some time)

But this will only get you around a 2 times improvement in speed.

So wouldn't it already make compiled GDScript faster than C# in most cases?
Better performance with a simpler language sounds like a nice deal to me.

So wouldn't it already make compiled GDScript faster than C# in most cases?

Likely not, given that it would have to pass through the whole Variant layer of indirection. Looking at languages such as Wren, it seems that using NaN-tagging or unboxed types is more detrimental to performance than compiling things to machine code. C# has both unboxed types _and_ JIT compilation, so compiling GDScript to machine code won't magically make it faster than C#.
Note that GDScript already has a pretty optimized bytecode dispatcher, having machine code to do the same would not speedup the bottleneck.

Well, maybe a good solution would be something that generates the unoptimized c++ code from the gdscript (perhaps the sconscript file too) and then the user would optimize (it should not be a big deal since the user wrote the original script) and compile it manually .

It's not perfect but it's faster already than doing everything by hand.

If you are going to write the code twice, why not write it in C++ directly?

That's another thing about translating GDScript directly to LLVM, can AOT a binary for any platform, not just on the one you are currently on and cross-compileables.

This issue reminds me of the Boo language. A python inspired language running on .NET.

I don't know what it's worth (I haven't really used it tbh), and the project seems dead (5 years? Damn...) but I'm tossing it in anyway.

I prefer Kotlin's type declaration. It's more readable

var name:String = "Bob"

@Logmytech You are half an year late, Typed GDScript is already in master (and happens to use Kotlin-ish type declarations).

Ruby has a new JIT compiler: https://bugs.ruby-lang.org/projects/ruby/wiki/MJIT#MJIT-organization

Just curious, is this planned for 4.0?

@girng, there is a suspicion that this will not happen in Godot 4.0. But it is not exactly :)

I think v4.0 could have preliminary GDScript-to-C transpiling, just like v3.0 had preliminary C# support.
(if we're lucky enough).

It’s easier to make support for the ZIG language. Promising language. Although I really like the GDScript, and if it worked faster it would be very cool. By the way, it would be great if it were not for the file itself to be a class; the class was written in the file, as is done in other languages. Because of this feature, some difficulties arise which could easily be eluded.

Godot 4.0 most likely won't have JIT, but it will have performance improvements in GDScript.

I have done significant work toward compiling GDScript to C with GDNative. I have arrived at a point where I am not convinced that it is a worthwhile endeavor to complete. Theoretically the performance of AOT code could be orders of magnitude faster than GDScript in execution, but in practice the results are more disappointing. The costs of going through the GDNative layer are significant, and without major changes to GDScript itself the compiled code is very brittle (GDScript bytecode is not generated in a way that is safe to run in a later execution because it expects the environment to be static, including positions of things in the engine’s internal arrays).

I am however convinced that by implementing a minimal amount of back-end optimizations that some real performance improvements could be realized.

I am working on a fork that includes a number of optimizations that require no significant changes to GDScript at all, but already nets some performance gains.

So far I have implemented the boilerplate data structures to perform code optimization, as well as a few basic optimization passes:

  • construction and destruction of control flow graph
  • data flow analysis including gens and kill sets, live ranges
  • dead code elimination
  • jump threading (important optimization) as GDScript creates much unneeded branching

As a POC I plan to implement a few more passes prior to pushing up my fork:

  • common subexpression elimination
  • type inference of temporaries and native arithmetic for temporaries (I am also not convinced typed arithmetic will be a huge win)

Typed arithmetic operations do require modifications to the GDScriptFunction and function state classes to include arrays of typed registers, as well as new opcodes to address typed registers and avoid additional type checking at runtime.

You can see my progress on the above mentioned optimizations in my godot fork, https://github.com/pchasco/godot/tree/gdscript-optimization/modules/gdscript/optimizer

@pchasco You may want to talk to @vnen, who is currently reworking GDScript for Godot 4.0 - IMO, this would be a good time to make sure to get such low-hanging fruit in :)

See https://godotengine.org/article/gdscript-progress-report-writing-tokenizer

@pchasco You may want to talk to @vnen, who is currently reworking GDScript for Godot 4.0 - IMO, this would be a good time to make sure to get such low-hanging fruit in :)

See https://godotengine.org/article/gdscript-progress-report-writing-tokenizer

http://blog.moblcade.com/?p=114

Well, the VM is gonna change to integrate typed instructions so I'm not sure if doing optimization work now is the best. I do believe that those ideas can be used in the new VM, but it'll take a while until it's completed.

I'm not sure if we'll ever have JIT though, so maybe this issue could be closed in favor of something else. There's an idea of doing AOT compilation which would be easier to manage than this.

@vnen Yeah the issue title isn't fitting anymore, if you read the above they found JIT not to be worth it mostly and instead went for targeted optimizations in the current interpreter.

It may be worthwhile to keep those in mind while reworking that, but yeah, you'll know way better than me when a good time is to see about those :) just wanted to connect you two

http://blog.moblcade.com/?p=114

@pchasco You may want to talk to @vnen, who is currently reworking GDScript for Godot 4.0 - IMO, this would be a good time to make sure to get such low-hanging fruit in :)
See https://godotengine.org/article/gdscript-progress-report-writing-tokenizer

http://blog.moblcade.com/?p=114

I see you found my blog!

Well, the VM is gonna change to integrate typed instructions so I'm not sure if doing optimization work now is the best. I do believe that those ideas can be used in the new VM, but it'll take a while until it's completed.

I'm not sure if we'll ever have JIT though, so maybe this issue could be closed in favor of something else. There's an idea of doing AOT compilation which would be easier to manage than this.

I agree that JIT is not a workable solution given the number of platforms, varying hardware, and amount of work necessary to maintain. AOT is definitely the simplest and the most portable solution for native performance with GDScript. In fact Unity transpiles .NET to C++ for its AOT also. I would be interested in contributing with the GDScript rewrite.

@pchasco I'd suggest joining the #godotengine-devel IRC channel and get in contact there :)

As I mentioned before it's very unlikely that we'll add JIT. There are some other ideas in the discussion but no conclusion.

Since we are moving proposal to the GIP tracker, I'll close this one and if someone has an idea, please open a new proposal (after looking if nobody else did it first). This issue can be linked in relevant proposals to keep the discussion history.

Some contributors have different ideas for AOT compilation, but I'll let them open a proposal with what they have in mind.

@vnen
Then please update the Roadmap, it's misleading people.

Well, I even forgot the roadmap existed, it isn't updated in a long time.

@vnen
You forgot, but other users didn't. So please update it, because many are keeping it in mind.

interpreters are garbage and to me that kills what usefulness gd script has when the performance is abysmal

you use an interpreter when you are writing a basic emulator, not a fully fledged game engine

a just in time compiler might often be faster than a slow, outdated ass compiler anyway, the interpreter system is just plain and simple bad, and i feel like i would rather rip out gd script and just go purely with c++, and just make a ghetto setup with a just in time system

i think people are not willing to admit that the interpreter is crap since people don't want to hurt each other feelings for some reason, but compared to c++, the end result is pretty, ehhh...

it's.... okay if you have something really basic going on i guess, but, for anything serious it's just, like it's not suitable for much of anything in my mind, beyond really simple games

@RaTcHeT302 no need to bring your negativity in and remember that we have a Code of Conduct. There are plans to optimize GDScript in many ways, including compilation to native code, just not with JIT. Also if you compare with C++ even a JITed runtime will be slow.

@vnen: Just sayin' that LuaJIT is nearly up there with C/C++ on performance benchmarks - but there is a widespread belief that magic is involved :smile:

JIT is not possible on all Major platforms. It is better to focus efforts
where all can take advantage of them. Ahead of time compilation is the only
100% compatible technology.

On Sun, Aug 9, 2020 at 8:46 AM Zireael07 notifications@github.com wrote:

@vnen https://github.com/vnen: Just sayin' that LuaJIT is nearly up
there with C/C++ on performance benchmarks - but there is a widespread
belief that magic is involved 😄

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/5049#issuecomment-671047838,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFIAGK3S7RA3DRXW6NUC3R72LCVANCNFSM4CFZMZPA
.

Aren't there downsides to AoT compared to JIT? For example what about dynamically generated or loaded scripts? JIT shouldn't have a problem optimizing them, but AoT?

By the way, on what major platform is not JIT possible? I thought Java with its JIT runs pretty much everywhere.

Edit: Oh, I guess Apple is the problem, the one prohibiting use of JIT. So it's an arbitrary vendor-lock limitation, not a technical one. Glad I don't have to support any Apple devices...

iOS does not allow JIT for applications distributed through the App Store
unless it is using Apple’s browser component.

AOT would not be possible for dynamic scripts.

On Sun, Aug 9, 2020 at 11:15 AM monnef notifications@github.com wrote:

Aren't there downsides to AoT compared to JIT? For example what about
dynamically generated or loaded scripts? JIT shouldn't have a problem
optimizing them, but AoT?

By the way, on what major platform is not JIT possible? I thought Java
with its JIT runs pretty much everywhere.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/5049#issuecomment-671064117,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFIACWWCWDXO4NZ7GCL63R724RHANCNFSM4CFZMZPA
.

iOS, Web and a few console platforms do not support JIT compilation.

There's a rumor that AOT is now thrown out of the deck with JIT. I hope, that's not true. Somebody, please tell me, is it true?

Are you saying there is a rumor AOT would no longer be allowed on some
devices? That’s literally impossible, unless I’m misunderstanding something?

On Wed, Sep 30, 2020 at 5:47 AM Teashrock notifications@github.com wrote:

>
>

@Calinou https://github.com/Calinou @neikeq https://github.com/neikeq
@reduz https://github.com/reduz @akien-mga
https://github.com/akien-mga

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/5049#issuecomment-701313134,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFIADVHAXMGBOL3YEDVILSIMEEFANCNFSM4CFZMZPA
.

@pchasco
No. I mean, somebody told me that GDScript will have neither AOT nor JIT.

Maybe it will not be officially supported, but I can confirm that the new
GDScript architecture outlined by vnen is capable of supporting it. An
enterprising developer could implement a custom module to do AOT to
GDNative C.

On Wed, Sep 30, 2020 at 11:16 AM Teashrock notifications@github.com wrote:

>
>

@pchasco https://github.com/pchasco

No. I mean, somebody told me that GDScript will have neither AOT nor JIT.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/5049#issuecomment-701494412,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFIACAKZVJQK2CHTDJT63SINKXDANCNFSM4CFZMZPA
.

@pchasco

maybe

So, you don't know. "Capable of supporting" doesn't mean "will support".

@Teashrock We don't know if GDScript will feature JIT or AOT compilation in 4.0, but it's not very likely. Maybe in 4.1 or later…

If you need higher performance for number crunching purposes (i.e. your CPU limitations clearly come from the scripting language), use C#. But first, read the optimization tutorials :slightly_smiling_face:

@Calinou
It's just that they talked about 4.0 regarding JIT/AOT. And now you're saying me about 4.1. Why's that? How's that? Somebody, just give everyone a clear public anwser, which won't be somewhere deep on GitHub.

Thank you in advance.

Was this page helpful?
0 / 5 - 0 ratings