3

我一直在开发数据流/图表风格的内部 DSP 应用程序(Java 带有 Groovy/Jython/JRuby 的钩子,通过 OSGi 的插件,大量的 JNI),类似于纯数据和 simulink。我目前的设计是推模型。用户与某些源组件交互,使其将数据推送到下一个组件,依此类推,直到结束块(通常是显示或文件写入器)。这种设计存在一些独特的挑战,特别是当组件缺乏输入时。没有简单的方法来请求更多的输入。我已经通过反馈控制流缓解了其中的一些问题,例如 FFT 块可以广播它需要更多数据来作为其链的源块。我已经考虑添加对组件的支持是推/拉/两者。

我正在寻找有关推送与拉动与两者/混合的优点的回应。你以前做过吗?有哪些“陷阱”?你是如何处理它们的?这个问题有更好的解决方案吗?

4

2 回答 2

2

在大型产品中使用“大部分拉动”方法的一些经验:

模型:节点构建一个 1:N 树,即每个组件(根除外)有 1 个父级和 1..N 个子级。数据几乎完全从父母流向孩子。更改通知可以来自树中的任何节点。

实现:通过发送节点的 id 和“生成”计数器通知所有叶子。叶子知道它们依赖于哪个节点路径,因此它们知道是否需要更新。(任何其他子节点更新算法也可以,事后看来可能会更好)。

Leafs 向其父级查询当前数据,递归地查询冒泡。包括生成计数器,因此冒泡在始发节点处停止。

好处:

  • 父节点不需要太多/任何关于其子节点的信息。任何人都可以使用数据——这允许一种通用方法在用于显示的数据之上实现一些(最初不是预期的)非 UI 功能
  • 子节点可以聚合和延迟更新(避免重绘肯定胜过快速绘制)
  • 不活动的叶子确实不会导致任何数据流量

缺点

  • 由于发布了完整的数据,增量更新的成本很高。该实现实际上允许请求不同的数据包(并且生成计数器可以防止不必要的数据流量),但最初设计的数据包非常大。切片它们是事后的想法,但工作正常。
  • 你需要一个真正好的生成机制。最初实现的与初始更新(需要特殊处理 - 请参阅“增量更新”)和更新聚合相冲突
  • 数据在树上传播的需求大大低估了。
  • 只有当节点提供对当前数据的只读访问时,发布才便宜。不过,这可能需要额外的更新同步
  • 有时您希望中间节点更新,即使所有叶子都处于非活动状态
  • 一些叶子最终实现了轮询,一些基本节点最终依赖于此。丑陋。

一般来说:

当数据和处理层对 UI 一无所知时,Data-Pull 对我来说“感觉”更加原生。但是,它需要复杂的更改通知机制来避免“更新宇宙”。

Data-Push 简化了增量更新,但前提是发送者非常了解接收者。

我没有使用其他模型的类似规模的经验,所以我无法真正提出建议。回想起来,我发现我大部分时间都在使用 pull,这不那么麻烦。看看其他人的经历会很有趣。

于 2009-06-11T14:01:43.153 回答
0

我在一个纯拉图像处理库上工作。它更适合批处理式操作,我们不必处理动态输入,因此它似乎工作得很好。Pull 对于大型数据集和线程特别有效:我们线性扩展到至少 32 个 CPU(当然,取决于正在评估的图形,呵呵)。

我们有一个 GUI,它允许叶子成为动态数据源(例如,传送帧的摄像机),并且通过丢弃和重建图表的相关部分来处理它们。在我们的例子中这很便宜,所以开销并不高。

于 2009-06-11T15:24:01.787 回答