emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Add more supported primitives in libgccjit IR (was: Shrinking the C


From: Gregory Heytings
Subject: Re: Add more supported primitives in libgccjit IR (was: Shrinking the C core)
Date: Mon, 21 Aug 2023 09:42:37 +0000



Just to get something going, I executed https://elpa.gnu.org/packages/elisp-benchmarks.html benchmarks and looked into the primitives that take significant amount of time:

3.85% emacs emacs [.] arith_driver
2.62% emacs emacs [.] Fgtr
2.31% emacs emacs [.] check_number_coerce_marker
2.24% emacs emacs [.] Fmemq
2.20% emacs emacs [.] Flss
1.56% emacs emacs [.] arithcompare
1.12% emacs emacs [.] Faset
1.10% emacs emacs [.] Fcar_safe
0.97% emacs emacs [.] Faref
0.94% emacs emacs [.] Fplus
0.93% emacs emacs [.] float_arith_driver
0.58% emacs emacs [.] Feqlsign

We may consider directly supporting some of these functions in native compile libgccjit IR code to get rid of runtime type checks.


I'm not sure elisp-benchmarks are representative enough of actual Elisp code, but this is an excellent example of what Alfred tries to convey.

Look at data.c:arith_driver. You'll see that it's essentially a function which dispatches the handling of its arguments depending on their type: if the arguments are integers, do something, else if the arguments are floats, do something, else if the arguments are bignums, do something.

Now look at data.c:Fgtr or data.c:Flss. You'll see that it calls arithcompare_driver, which calls arithcompare, which again dispatches the handling of the arguments depending on their types: integer, float, bignum.

These integer/float/bignum types are not known at compilation time, because Elisp is a dynamically typed language, which means that the type of an object can change over its lifetime, an object could be an integer at some point of time, and later a float, and later again a bignum. In a statically typed language, these type dispatch operations can be bypassed, because it is known at compilation time that the arguments are, say, integers, and that we can simply call the "add" instruction to compute their sum.

So, in a statically typed language, adding two integers takes a single CPU cycle. In a dynamically typed language, it can take many CPU cycles. And of course, using a JIT compiler does not magically transform a dynamically typed language into a statically typed one: you still need to do these dynamic dispatches.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]