【问题标题】:Boost.Spirit Alternative Parser parallelizationBoost.Spirit 替代解析器并行化
【发布时间】:2018-08-29 04:45:51
【问题描述】:

我正在使用具有许多替代子规则的 x3 规则解析缓冲区。 实际上,我有来自不同 GPS 设备的数据,我的主要解析器如下所示:

 auto gps_r = device1_r | device2_r | device3_r;

 bool ok = x3::parse(...,gps_r,..);

我知道我可以为输入数据和每个设备规则并行调用x3::parse()。但这可能不适用于某些递归解析(例如 SAX DOM 解析)。

我的问题更具理论性:是否有任何尝试使 Alternative Parser 异步(例如,使用 boost.coroutines2)以进行并行解析?

【问题讨论】:

  • 如果您发现任何关于它的信息,我很想知道。我也可以用。
  • 没有。我非常怀疑这将是一个净性能胜利。我认为这是有益的唯一领域是对 large 消息进行输入 validation (例如校验和/摘要计算),即使在这里它也将在协议生效时缺乏并且只是“检查所有可能的格式”似乎与安全编程实践背道而驰(通过恶意负载打开尽可能多的 DOS/攻击向量)
  • 如果你有具体的例子,我们可能会想出现有的方法(例如,当creating a static Lexer 时,静态替代的所有路径都被编译成确实执行的 1 个状态机并行处理所有“分支”的工作量最少,就像正则表达式的 DFA 表示一样)
  • 好的,我明白了。感谢您提供词法分析器的链接。真实示例:解析 xml/json 文件(10Mb)。即使处理简单的 json : {"foo" : 1, "bar" : { "sub" : false }},我们也有一些规则,比如 'auto json_r_def = x3::char_ >> value_r |数组_r | json_r;'。这实际上意味着我们正在对不同规则的相同数据进行顺序处理。在这里提高性能的唯一方法是并行执行。

标签: c++ boost boost-spirit


【解决方案1】:

通常没有并行化的空间,因为组合语法试图执行尽可能少的前瞻和回溯。在这种情况下,并行解析的任何好处都将被线程生成和同步开销所抵消。

如果您的语法实际上像所示示例一样从头开始分支 - 您可以重写它以并行运行多个 x3::parse

目前的 Spirit 替代解析器实现也存在问题,因为它不会展平表达式树(虽然它是二叉树,但通常非常不平衡)。

【讨论】:

  • 最后一点是非常有见地的花絮,但我认为它只会伤害编译时间,而不是其他什么?我想我可以创建一个自定义解析器来执行并行替代 like here 但就像你确认的那样,我认为如果这“有帮助”,那么就会出现某种规模的协议设计错误。
  • 我不认为它会影响编译时间,扁平化将需要更多的模板实例化,并且递归深度可以忽略不计来推动内联。
猜你喜欢
  • 1970-01-01
  • 2014-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多