从多个线程使用 QuantLib 的正确方法是啥?

Posted

技术标签:

【中文标题】从多个线程使用 QuantLib 的正确方法是啥?【英文标题】:What is the right way to use QuantLib from multiple threads?从多个线程使用 QuantLib 的正确方法是什么? 【发布时间】:2017-10-25 13:50:55 【问题描述】:

我无法找到任何明确描述 QuantLib 的线程安全属性(或没有它们!)的文档。 QuantLib configuration documentation 列出了一些与线程安全相关的编译时选项,据我推断,默认情况下,QuantLib 并不完全是线程安全的。

具体有:

QL_ENABLE_SESSIONS - “如果已定义,单例将为不同的会话返回不同的实例。您必须在命名空间 QuantLib 中提供并与库链接一个 sessionId() 函数,为每个会话返回不同的会话 ID。未定义默认情况下。”

QL_ENABLE_THREAD_SAFE_OBSERVER_PATTERN - “如果定义,将使用观察者模式的线程安全(但性能较低)版本。如果您想通过 JVM 或 .NET 中的 SWIG 层使用 QuantLib,则应该定义它生态系统或任何具有异步垃圾收集器的环境。默认情况下未定义。"

QL_ENABLE_SINGLETON_THREAD_SAFE_INIT - “定义此项以使单例初始化线程安全。默认情况下未定义。与多个会话不兼容。”

如果我想使用 QuantLib,我应该使用哪些选项,以及我应该采取哪些其他步骤:

    来自多个线程,但从不同时(例如仅在持有全局锁时)?

    同时来自多个线程,但它们之间不共享任何对象?

    同时来自多个线程,在它们之间共享对象?

我的应用程序的自然结构是有向无环图,在一端输入恒定的市场数据流,用于计算和更新各种对象,并在另一端产生估计价格流。我非常希望能够让多个内核并行工作,因为某些计算需要很长时间。

该应用程序将主要用 Java 编写,用 C++ 编写最少的部分以与 QuantLib 交互。我不打算使用 SWIG 包装器。我很高兴在没有 Java 垃圾收集器帮助的情况下对 QuantLib 对象进行内存管理。


编辑!如果您决定设置这些选项中的任何一个,那么在 unix 上,使用 ./configure 的相应标志进行设置:

--enable-sessions
--enable-thread-safe-observer-pattern
--enable-thread-safe-singleton-init

【问题讨论】:

【参考方案1】:

SmallChess 的答案与事实相去甚远。 QuantLib 中几乎没有锁或安全网,因此大多数人如果需要在处理器上分配计算,就会使用多处理——这是有充分理由的。

对于那些想要更深入了解并且支持在 QuantLib 中使用多线程的人:

无论你做什么,如果可能的话,启用配置开关来给你一些安全,例如用于单例的线程安全初始化的配置开关(有一个警告,见下文);

李>

如果它们不共享任何对象,并且如果它们不尝试修改全局变量(例如评估日期),您可能会同时运行多个线程(查找继承的类来自 Singleton 的全局列表)。

如果您需要不同线程的不同评估日期,您可以使用另一个编译开关来构建 QuantLib,以便单例实际上不是单例,但每个线程都有一个实例。警告:此开关与单例的线程安全初始化不兼容。你仍然不应该在线程之间共享对象。

如果您想共享对象,您可能会遇到比其价值更多的麻烦。问题是:(1)对基础数据的任何更改,例如曲线,都会触发重新计算; (2) 重新计算(例如曲线的引导)不会立即执行,而是仅在需要时执行,即调用某个曲线方法时。这意味着您必须将各个步骤分开:首先,设置任何引号的值并确保没有任何进一步的更改;然后,绕过曲线并触发重新计算,例如在某个日期询问折扣因子;最后,将曲线传递给工具并对其定价。在计算期间更改值将导致在它们中间进行引导;并且在计算之前不触发完整的构建可能会导致两个仪器同时触发两个引导程序,这对任何相关方来说都不会很好。

正如我所说,这可能比它的价值更麻烦。理想情况下,不要在线程之间共享对象,也不要接触全局变量。否则,更喜欢多处理。

【讨论】:

【参考方案2】:

不幸的是,QuantLib 不是线程安全的。您拥有的任何选项都不会帮助您。 QuantLib 是一个免费项目,它的重点是实际的数学建模,而不是线程安全等计算优化。

您绝对应该将 QuantLib 包装在一个进程中。对于 QuantLib,鼓励使用多线程,除非您绝对知道自己在做什么并检查了相关的源代码。

【讨论】:

当你说“你所拥有的任何选择都不会帮助你”时,你的意思是他们没有做我认为他们做的事情,或者他们不工作,或者他们不是出于某种原因就足够了,还是什么? @TomAnderson 他们不会做你想做的事。请搜索 QuantLib 邮件列表,有一些关于线程安全的帖子。取决于你想做什么,一些代码函数是线程安全的,因为它们不使用全局变量。 @TomAnderson 例如,如果您只想计算 Black Scholes。它绝对是线程安全的,因为 BlackScholesCalculator 没有全局依赖。 @TomAnderson 总的来说,该项目不提供线程安全保证,但没有全局依赖的函数可能是线程安全的。 @TomAnderson 例如,需要全局评估日期变量的函数不能是线程安全的。

以上是关于从多个线程使用 QuantLib 的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何从nodejs express.js中的一个用户帐户管理多个登录的正确方法是啥?

指定“WITH NAME”以从单个测试用例访问多个机器人框架远程服务器的正确方法是啥?

使用 socket.io 管理多个聊天室的正确方法是啥?

使用多个 ID 时在 JPQL 中执行 CRUD 操作的正确方法是啥

使用 Prisma 和 Apollo 调用多个 GraphQL 突变的正确方法是啥

捕获在不同线程中运行的方法异常的正确方法是啥?