我有一个父进程,它产生了几个子进程来进行一些CPU密集型工作。对于每批工作,父进程需要向子进程发送几个100MB的数据(作为一个单块),一旦完成,它必须接收大约相同数量的数据(再次作为一个单块)。 父进程和子进程是不同的应用程序,甚至是不同的语言(主要是Python和C ++),但如果我有任何C / C ++解决方案,我可以根据需要编写Python包装器。
我认为最简单的方法是使用管道。这有许多优点,例如主要是跨平台,简单和灵活,我甚至可以在以后扩展我的代码而无需过多的工作来通过网络进行通信。
但是,现在我正在分析整个应用程序,我发现通信中有一些明显的开销,我想知道是否有更快的方法。我的案例(科学研究)并不真正需要跨平台,如果它适用于Ubuntu> = 12左右就足够了(虽然MacOSX也不错)。原则上,我认为将大量数据复制到管道中并在另一端读取它不应该比设置一些共享内存和执行memcpy
花费更多的时间。我错了吗?或者你预期会有多大的表现呢?
剖析本身很复杂,我没有真正可靠和准确的数据,只有线索(因为它是一个非常复杂的系统)。我想知道我现在应该把时间花在哪里。试图获得更准确的分析数据?试图实现一些共享内存解决方案,看看它有多大改进?或者是其他东西?我还想过在库中包装和编译子进程应用程序并将其链接到主进程,从而避免与另一个进程的通信 - 在这种情况下,我只需要一个memcpy
。
StackOverflow上有很多相关的问题,但我还没有真正看到不同通信方式的性能比较。
答案 0 :(得分:2)
好的,所以我写了一个小的基准测试工具here,它通过共享内存或通过管道复制一些数据(~200MB)10次。
使用MacOSX的MacBook上的结果:
Shared memory:
24.34 real 18.49 user 5.96 sys
Pipe:
36.16 real 20.45 user 17.79 sys
所以,首先我们看到共享内存明显更快。请注意,如果我复制较小的数据块(~10MB),我几乎看不到总时间的差异。
第二个明显的区别是在内核中花费的时间。预计管道需要更多内核时间,因为内核必须处理所有这些读写操作。但我不会指望它那么多。