Re: Performance implications of large FFI constants

  • From: Peter Colberg <peter@xxxxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Thu, 27 Sep 2012 14:56:56 -0400

On Thu, Sep 27, 2012 at 07:42:49PM +0200, Mike Pall wrote:
> Peter Colberg wrote:
> > Could one define non-integral constants more efficiently as well,
> > without resorting to a Lua table on top of a C library namespace?
> 
> Sorry, no. 'static const' is restricted to integers right now.

How far could you theoretically take the 'static const' construct?

For the MPI ABI, casts and pointer assignment would be convenient.

    /* MPICH2 */
    static const struct MPI_Comm *__ptr32 MPI_COMM_WORLD = (struct MPI_Comm 
*__ptr32) 0x44000000;
    /* OpenMPI */
    static const struct MPI_Comm *MPI_COMM_WORLD = (struct MPI_Comm *) 
&ompi_mpi_comm_world;

Both seems to be legal C99 code (gcc -std=c99 -Wall -Werror).

The latter is almost possible using extern struct, however this
results in a reference (struct MPI_Comm &) instead of a pointer:

    extern struct MPI_Comm MPI_COMM_WORLD asm("ompi_mpi_comm_world");

Note that *__ptr32 is a work around to represent 'int' handles, which
allows the assignment of FFI metatypes to the different handle types.
This nicety is a result of some MPI implementations favouring Fortran.

> > Is there a better way of binding the above with LuaJIT?
> 
> I guess not. For an API that ugly, one would probably want to
> copy-and-paste the #define mess.

Then you have not seen the HDF5 C ABI :-). Brace yourself:

#define H5CHECK          H5check(),

#define H5F_ACC_RDONLY  (H5CHECK 0x0000u)
#define H5F_ACC_RDWR    (H5CHECK 0x0001u)
#define H5F_ACC_TRUNC   (H5CHECK 0x0002u)
#define H5F_ACC_EXCL    (H5CHECK 0x0004u)
#define H5F_ACC_DEBUG   (H5CHECK 0x0008u)
#define H5F_ACC_CREAT   (H5CHECK 0x0010u)

That's right, constants smuggle in a non-inline function call to H5check().

> Alas, implementing C pre-processor defines and macros is still on
> my TODO list. But I don't think it'll make it for LuaJIT 2.0.0.
> Maybe in a later dot release, since it's upwards-compatible. Or,
> more likely, in LuaJIT 2.1.

A preprocessor would certainly be welcomed by many. On the other hand,
macros part of an API can be (ab)used to introduce arbitrary C code,
that is impossible to translate to proper FFI bindings without manual
labour.

For MPI, I am using a two-stage bindings generator. The first stage
pipes a Lua script through the MPI C preprocessor to evaluate enum
values and preprocessor constants, and the second stage runs the
output, translating a template with FFI bindings to a customized
Lua module.

http://git.halmd.org/luajit-mpi.git/tree/mpi/C_gen.lua.in
http://git.halmd.org/luajit-mpi.git/tree/mpi/C.lua.in

Hello, World already works on many scientific clusters:

http://halmd.org/luajit-mpi/#tutorial

This means LuaJIT now scales to thousands of CPU cores :-).

Peter

Other related posts: