Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux IPC共享内存和线程内存的性能差异_Linux_Multithreading_Ipc_Shared Memory - Fatal编程技术网

Linux IPC共享内存和线程内存的性能差异

Linux IPC共享内存和线程内存的性能差异,linux,multithreading,ipc,shared-memory,Linux,Multithreading,Ipc,Shared Memory,我经常听说,与在线程之间访问进程内存相比,在进程之间访问共享内存段不会带来性能损失。换句话说,多线程应用程序不会比使用共享内存的一组进程更快(不包括锁定或其他同步问题) 但我有疑问: 1) shmat()将本地进程虚拟内存映射到共享段。必须对每个共享内存地址执行此转换,这可能会带来很大的成本。在多线程应用程序中,不需要额外的转换:所有VM地址都转换为物理地址,就像在不访问共享内存的常规进程中一样 2) 共享内存段必须由内核以某种方式进行维护。例如,当所有附加到shm的进程都被取下时,shm段仍然

我经常听说,与在线程之间访问进程内存相比,在进程之间访问共享内存段不会带来性能损失。换句话说,多线程应用程序不会比使用共享内存的一组进程更快(不包括锁定或其他同步问题)

但我有疑问:

1) shmat()将本地进程虚拟内存映射到共享段。必须对每个共享内存地址执行此转换,这可能会带来很大的成本。在多线程应用程序中,不需要额外的转换:所有VM地址都转换为物理地址,就像在不访问共享内存的常规进程中一样

2) 共享内存段必须由内核以某种方式进行维护。例如,当所有附加到shm的进程都被取下时,shm段仍然处于运行状态,并且最终可以被新启动的进程重新访问。shm段上的内核操作可能会有一些开销


多进程共享内存系统是否与多线程应用程序一样快?

设置共享内存需要内核做一些额外的工作,因此从进程中附加/分离共享内存区域可能比常规内存分配慢(或者可能不是……我从未做过基准测试)。但是,一旦连接到进程虚拟内存映射,共享内存就与任何其他用于访问的内存没有什么不同,除非有多个处理器争夺相同缓存线大小的块。因此,一般来说,对于大多数访问,共享内存应该与任何其他内存一样快,但是,根据您放在那里的内容以及有多少不同的线程/进程访问它,对于特定的使用模式,您可能会遇到一些减速。

除了附加()和分离(
shmdt
)共享内存的成本之外,访问速度应该同样快。换句话说,它应该是快速的,因为硬件支持它。对于每个访问,不应该有额外的层形式的开销

同步也应该同样快。例如,在Linux中,进程和线程都可以使用a。原子变量也应该可以正常工作

只要连接/分离成本不占主导地位,使用流程就不会有任何不利因素。然而,线程更简单,如果您的进程大多寿命较短,那么附加/分离开销可能是一个问题。但是,由于创建流程的成本很高,无论如何,如果您关心性能,就不可能出现这种情况

最后,这个讨论可能很有趣:。(警告:它已经过时了。我不知道从那以后情况是否发生了变化。)

这一相关问题也可能有帮助:
(简短的回答是:不多。)

共享内存的成本与对其进行的“元”更改的数量成正比:分配、解除分配、进程退出

内存访问的次数不起作用。访问共享段的速度与访问其他任何位置的速度一样快

CPU执行页表映射。在物理上,CPU不知道映射是共享的

如果遵循最佳实践(即很少更改映射),您将获得与进程私有内存基本相同的性能

1) shmat()将本地进程虚拟内存映射到共享 段必须对每个共享内存执行此转换 地址和可表示相对于数量的重大成本 shm访问的数量。在多线程应用程序中,没有额外的 需要转换:所有VM地址都转换为物理地址 地址,如在不访问共享内存的常规进程中

与常规内存访问相比,除了设置共享页(在调用
shmat()
的过程中填充页表)的初始成本之外,没有额外的开销。在大多数Linux版本中,每4KB共享内存有1页(4或8字节)

无论页面是分配共享的还是在同一个流程中,成本都是相同的

2) 共享内存段必须由内核以某种方式进行维护。 我不知道“不知何故”在表演方面意味着什么,但是 例如,当所有连接到shm的进程都被关闭时, shm段仍在运行,最终可由新用户重新访问 启动进程。必须至少有一定程度的开销 与内核在生命周期内需要检查的内容相关 shm部分

无论是否共享,内存的每个页面都附加了一个“结构页面”,其中包含一些关于该页面的数据。其中一项是引用计数。当一个页面被分配给一个进程时[无论是通过“shmat”还是其他机制],引用计数都会增加。通过某种方式释放时,引用计数递减。如果递减的计数为零,则页面实际上被释放-否则“不会再发生任何事情”

与分配的任何其他内存相比,开销基本为零。同样的机制也用于页面的其他用途——比如说,你有一个页面也被内核使用——而你的进程死掉了,内核需要知道在内核和用户进程释放该页面之前不要释放该页面

创建“fork”时也会发生同样的情况。当一个进程被分叉时,父进程的整个页面表基本上被复制到子进程中,并且所有页面都被设置为只读。每当写操作发生时,内核就会出现一个错误,导致该页被复制,因此现在该页有两个副本,进行写操作的进程可以修改它的页,而不会影响其他进程。一旦孩子(或父母)亲