我正在尝试通过C ++多线程解决网络流问题。
给定一个网络(所有节点都通过弧连接,每个弧连接到2个,只有2个结束节点,一个是输入节点,另一个是输出节点,每个节点可以有多个输入弧和输出弧),每个节点需要做一些计算然后交换 将结果数据计算到其连接的输入和输出节点。
可以将多个节点分组为一个任务,该任务由一个线程运行。就这样, 整个网络计算工作负载可以划分为多个任务。所有这些任务 被推入一个提升线程池,以便所有线程可以同时运行任务 时间。
但是,如果一个节点(在线程任务中)需要与另一个节点进行数据交换(在另一个节点中) 线程任务),存在同步问题。数据接收器需要等待数据 在数据发送方的数据缓冲区中可用。
我的程序员需要对网络进行分区,以便分配每个线程的任务工作负载 尽可能均匀。 如果所有线程共享一个大的数据缓冲区结构,则程序并行性不是 好,因为临界区太大了。有些线程必须等待 一个大型数据缓冲区结构即使是数据结构的一部分也解锁了 对他们有用)已经可以读或写。
例如,一大数据缓冲区结构具有以下缓冲区单元格: cell1,cell2,cell3,cell4。
当线程1尝试写入单元格1时,它必须锁定整个数据缓冲区结构 线程2无法读取或写入单元格2等。
因此,我想将一个大的数据缓冲区结构分解为多个不同的数据单元 根据线程号,使每个单元格只保存一个线程所需的数据 任务。
例如,如果我们有2个线程,我们创建2个数据单元,用于保存4所需的数据 线程分开。 如果我们有4个线程,我们创建4个数据单元,分别保存4个线程所需的数据。 等等。
我的问题是:
(1)如何设计数据单元?您可以看到它的大小基于线程数。
(2)如何减少同步开销?关键部分很小但是 如果节点间数据交换频率高,则创建和释放互斥锁的开销可能非常高。
(3)当节点的计算完成并且数据被写入其单元时,如何通知数据 接收器节点使得通知messgae仅由等待线程接收 运行接收器节点计算任务。所有其他不相关的节点和线程都不是 影响。
该程序非常时间敏感,应该是消息交换的延迟 控制得非常严厉,尽可能减少。
非常感谢任何帮助。
由于
答案 0 :(得分:0)
我认为,处理此问题的常用方法是在线程之间设置消息传递基础结构。
每个线程都有一个消息队列。在您的示例中,假设节点N1被分配给线程1,节点N2被分配给线程2,并且在N1和N2之间存在边缘。然后,当线程1完成N1计算时,它会向线程2发送一条消息:
“向节点N2发送输入”
要向线程发送消息,您只需锁定该线程的消息队列并附加消息即可。您使用一个互斥锁和两个条件变量(queue_not_empty_condition和queue_not_full_condition)来实现有界队列。当一个线程想要等待新工作时,它就会在其消息队列中进入休眠状态。
要减少同步开销,您可能需要一种方法将多个消息放入队列(“批量发送”),同时锁定互斥锁一次。然后在一个线程中循环看起来像这样:
if (I can do work without communicating with other threads)
do that work
else
send all pending messages (in batches to each destination thread)
wait on my input queue and pop the messages off in a batch
但是,消息的“批处理”可能会以复杂的方式与有界队列进行交互。没有免费的午餐。