GHC ccall 安全 VS ccall 不安全

Posted

技术标签:

【中文标题】GHC ccall 安全 VS ccall 不安全【英文标题】:GHC ccall safe VS ccall unsafe 【发布时间】:2015-03-03 00:34:32 【问题描述】:

尊敬的 GHC/Haskell 大师,

我目前正在使用 GHC 编写一个(中型)Haskell 服务器应用程序,它(大量)通过 FFI 使用第 3 方 C 库函数。换句话说,在服务客户端请求时,服务器线程会进行多个 FFI C 调用。

目前我正在不安全地调用所有 C 函数 (unsafe ccall) 以尽量减少调用开销。但是这里的权衡是,不安全的 ccall 不能被 GHC RTS 抢占,这意味着所有其他 Haskell 线程都被阻塞,直到 C 函数返回。如果 C 函数花费的时间太长,这可能会出现问题。

另一方面,安全 ccalls 更昂贵,但它们将在单独的操作系统线程中运行,不会阻塞 GHC 的工作线程。

我想,我想在这里问的是,您如何明智地做出最佳选择是进行 safe ccall 还是 unsafe ccall?例如,如果 C 函数简短且微不足道,我不想进行昂贵的安全 ccall,但如果 C 函数需要很长时间才能返回(cpu-heavy 计算、IO 操作等),那么进行不安全调用是有问题,因为它会阻塞工作线程。 有没有一种近似的阈值t,这样如果C函数的完成时间比t长,那么就让它安全ccall,否则不安全ccall?

我希望这个问题有点道理,如果有不清楚的地方,请随时发表评论。

提前感谢您的帮助!

【问题讨论】:

【参考方案1】:

经验法则如下:

    让一切safe。 如果分析揭示了 FFI 调用开销中的性能问题,请仔细考虑 unsafe 的语义是否适合热点调用。 如果分析发现safe FFI 调用的开销存在性能问题,并且调用的语义分析表明unsafe 不会破坏任何东西,那么考虑更改为unsafe,如果最坏的情况-呼叫的案例时间预计将优于 1 毫秒。

不要跳过前两个步骤。 unsafe 的潜在问题不仅仅是阻止 RTS。

【讨论】:

是的,我同意这一点。默认情况下标记safe,除非您有一些分析表明是unsafe 修复的问题。这是一个很好的概述,blog.melding-monads.com/2011/10/24/…

以上是关于GHC ccall 安全 VS ccall 不安全的主要内容,如果未能解决你的问题,请参考以下文章

golang go方法ccall必须以()结束

Julia ccall windows

进行异步调用后删除asio套接字

逆向知识十一讲,识别函数的调用约定,函数参数,函数返回值.

逆向知识十一讲,识别函数的调用约定,函数参数,函数返回值.

简单实用的Makefile