haskell - GHC ccall 安全 VS ccall 不安全

标签 haskell ghc ffi

亲爱的 GHC/Haskell 大师,

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

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

另一方面,安全调用成本更高,但它们将在单独的操作系统线程中运行,并且不会阻塞 GHC 的工作线程。

我想,我在这里想问的是,你如何明智地做出最佳选择,是进行安全调用还是不安全调用?例如,如果 C 函数简短且琐碎,我不想进行昂贵的安全调用,但如果 C 函数需要很长时间才能返回(CPU 繁重的计算、IO 操作等),那么进行不安全调用就是有问题,因为它会阻塞工作线程。 是否有一种近似阈值t,以便如果C函数完成时间超过t,则将其设为安全ccall,否则设为不安全ccall?

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

非常感谢您提前提供的帮助!

最佳答案

经验法则如下:

  1. 确保一切安全
  2. 如果分析发现 FFI 调用开销存在性能问题,请仔细考虑 unsafe 的语义是否适合热点调用。
  3. 如果分析显示安全 FFI 调用的开销存在性能问题,并且调用的语义分析表明不安全不会破坏任何内容,那么请考虑如果预计最坏情况下的调用时间将优于 1 毫秒,则更改为不安全

不要跳过前两个步骤。 不安全比仅仅阻止RTS有更​​多的潜在问题。

关于haskell - GHC ccall 安全 VS ccall 不安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27780091/

相关文章:

haskell - 流融合在 Haskell 中是如何工作的?

haskell - GHCi 可以告诉我本地 Haskell 函数的类型吗?

haskell - 如何为名称中包含非字母字符的库定义 MIN_VERSION_𝑙𝑖𝑏 宏?

haskell - 如何在使用 GHC 编译的 Haskell 函数中找到分配?

struct - 如何在 scala native 中按名称访问结构成员?

rust - 使用不能声明为静态的函数在运行时初始化可变静态变量

list - 丢弃索引中的元素,元素元组

haskell - 链接到 Yesod 中没有 Haskell 标识符的静态文件

haskell - ghc-7.10 : Non type-variable argument (Use FlexibleContexts to permit this)

c - 编译 C 程序时无法链接到 Rust 编译的库