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

时间:2017-10-25 13:50:55

标签: c++ multithreading concurrency thread-safety quantlib

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

特别是:

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

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

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

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

  1. 从多个线程,但从不在同一时间(例如,仅在持有全局锁定时)?

  2. 同时从多个线程中,但不在它们之间共享任何对象?

  3. 同时从多个线程中共享对象?

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

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

    EDIT!如果您决定设置任何这些选项,那么在unix上,使用相应的标志来执行./configure:

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

2 个答案:

答案 0 :(得分:4)

SmallChess的回答与事实并不遥远。 QuantLib中几乎没有锁或安全网,因此如果需要在处理器上分配计算,大多数人都会使用多处理 - 并且有充分的理由。

对于那些想要更多洞察力的人,以及作为在QuantLib中使用多线程的认可:

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

  • 如果他们不共享任何对象,可能会同时运行多个线程,如果他们不尝试修改全局数据,例如评估日期(查找继承自Singleton的类以获取全局变量列表。

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

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

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

答案 1 :(得分:2)

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

您一定要将QuantLib包装在流程中。多线程鼓励使用QuantLib,除非您完全知道自己在做什么并检查了相关的源代码。