rubymacosgilfiddle

Ruby Fiddle and Global Interpreter Lock (GIL)


I am using Fiddle to call an external C Function for some heavy linear algebra calculations (Mac OSX).

The module definition looks like

  module BLAS
    extend Fiddle::Importer
    dlload $BLAS_PATH
    extern 'void cblas_dgemm(int, int, int, int, int, int, double, double*, int, double*, int, double, double*, int)'
    extern 'void cblas_dgemv(int, int, int, int, double, double*, int, double*, int, double, double*, int)'
.......

The libraries have been optimized for mac osx and can use all the cores available. Unfortunately when I call these functions from Ruby with Fiddle only one core is used and my understanding is that this happens because of the GIL.

Is there a way to release the lock during the execution of external functions?

I am using ruby 2.0.0-p247 (not the system Ruby).


Solution

  • In ruby 2.3 this is the default (see the issue on the ruby bug tracker).

    Prior to that, it doesn't look like it was exposed in the Fiddle api. There is a function in the ruby c API called rb_thread_call_without_gvl that does pretty much exactly what it says on the tin: it releases the gvl, calls the passed function, reacquires the gvl and returns. It's a little tricky to use - be sure to read the comments in thread.c.

    If you can't upgrade, I suspect your best bet is to write a very thin C layer that wraps calls with rb_thread_call_without_gvl and then use fiddle to call that wrapper library.