Ruby Fiddle 和全局解释器锁 (GIL)

Ruby Fiddle and Global Interpreter Lock (GIL)

我正在使用 Fiddle to call an external C Function for some heavy linear algebra 计算 (Mac OSX)。

模块定义看起来像

  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)'
.......

这些库已针对 mac osx 进行了优化,可以使用所有可用的内核。不幸的是,当我使用 Fiddle 从 Ruby 调用这些函数时,只使用了一个核心,我的理解是这是因为 GIL.

有没有办法在外部函数执行过程中释放锁?

我正在使用 ruby 2.0.0-p247(不是系统 Ruby)。

在 ruby 2.3 中,这是默认设置(请参阅 ruby 错误跟踪器上的 the issue)。

在此之前,它看起来不像是在Fiddleapi中暴露的。 ruby c API 中有一个名为 rb_thread_call_without_gvl 的函数,它的功能几乎与锡罐上所说的完全相同:它释放 gvl,调用传递的函数,重新获取 gvl 和 returns。使用起来有点棘手 - 请务必阅读 thread.c 中的评论。

如果您无法升级,我怀疑您最好的选择是编写一个非常薄的 C 层,用 rb_thread_call_without_gvl 包装调用,然后使用 fiddle 调用该包装器库。