我将设计一个简单的数据分析工具,通过有向图处理不同类型的数据。有向图可由用户稍微定制。每个节点将包含对传递数据的记录,分析和数学运算。除了在每个节点处进行额外处理之外,该图在许多方面类似于神经网络。一些节点对通过的数据元素执行简单操作,而其他节点具有复杂的算法。
如何多线程处理此有向图中的处理,以便以最快,最有效的方式从图中获取结果?内存不是问题,也不是初始化此任务所需的时间。
我想过几种不同的方法来多线程工作:
每个线程实例“跟随”进入此图中的起始节点的每个数据元素。当线程通过每个节点时,线程将继续使用此数据元素,在树中一直调用每个节点上的处理方法。这基本上要求每个数据元素进入系统一个线程。当然,一旦数据元素被传送到整个系统,线程就会被回收。这里的问题是当节点上存在两个传出边时 - 线程需要遵循两者(这是否意味着从线程池中拉出一个新线程?)。
为每个节点创建一个线程,并在每个图形边缘上创建一个数据缓冲区。节点上的工作线程将不断检查以保存实例中的数据,即一个线程需要更长的数据。这种方法的问题在于缓冲区固有的“轮询”,因为它有足够的数据来开始处理它 - 为简化任何图形配置的数据流可能需要付出很小的代价。
任何人都可以想到更好的方式,或者你推荐哪一种方式?我正在寻找通过系统的最小延迟和不断处理传入数据流的能力。
谢谢! 布雷特
答案 0 :(得分:3)
首先,产生无限量的线程(例如每个节点的线程)不是一个好主意。通常,您希望最多拥有比CPU内核多1.5-3倍的线程(例如,四核的6-12个线程)。
我建议使用thread-pool and tasks。在这种情况下,您的问题可以被重新定义为您的任务应具有的大小。
您提到的两种方法都是有效的,每种方法都有自己的优点和缺点。
每个数据输入一个任务应该易于实现,因为图形处理的算法将保持单线程。线程之间的上下文切换,同步和数据传递的开销几乎都没有。
如果节点上有两个传出边,则此单个任务必须同时遵循这两个边。这是用于图遍历的所有算法的标准部分,例如, depth-first search或breadth-first search。
每个图表节点的一个任务可以在图表有许多可以并行处理的“分支”的情况下改善延迟。然而,这种方法需要更复杂的图形处理设计,并且线程同步的开销会更高。实际上,多线程的成本可能高于并行处理图形所带来的好处。
当节点上有两个传出边时,您可以在线程池上创建两个新任务和队列。 (或者排队一个任务并继续处理另一个任务。)
更困难的问题是节点上有两个传入边缘。处理节点的任务必须等到两个边的数据都可用。
结论:我个人会从第一个选项开始(每个数据输入一个任务),看看你可以用多远来获得它。