Shared memory共享内存

网友投稿 2427 2022-05-29

计算机科学中,共享内存是指可以被多个程序同时访问的内存,目的是提供程序之间的通信或避免冗余拷贝。共享内存是程序之间传递数据的有效手段。根据上下文,程序可能在一个处理器上运行,也可能在多个独立的处理器上运行。

在单个程序内部使用内存进行通信,例如在其多个线程之间,也被称为共享内存。

三个处理器的共享内存系统

1      在硬件方面

在计算机硬件中,共享内存指的是多处理器计算机系统中可以被多个不同的中央处理单元(CPU)访问的随机存取内存(RAM)块。

共享内存系统可以使用:

1.         统一内存访问(UMA):所有的处理器统一共享物理内存。

2.         非统一内存访问(NUMA):内存访问时间取决于相对于处理器的内存位置。

3.         高速缓冲存储器架构(COMA):每个节点上处理器的本地存储器被用作高速缓冲存储器,而不是实际的主存储器。

共享内存系统相对来说比较容易编程,因为所有的处理器都共享一个数据视图,处理器之间的通信可以像访问同一位置的内存一样快。共享内存系统的问题是,许多CPU需要快速访问内存,很可能会缓存内存,这有两个复杂的问题:

1.         访问时间退化:当几个处理器试图访问同一个内存位置时,会引起争夺。试图访问附近的内存位置可能会导致错误的共享。共享内存计算机不能很好地扩展。一般支持10个以内的处理器。

2.         缺乏数据连贯性:每当一个缓存更新了可能被其他处理器使用的信息时,需要将变化反映给其他处理器,否则不同的处理器将使用不连贯的数据工作。这样的缓存一致性协议在工作良好的情况下,可以为多个处理器之间的共享信息提供极其高性能的访问。另一方面,它们有时会过载,成为性能的瓶颈。

交叉式交换机、Omega网络、HyperTransport或前端总线等技术可用于抑制瓶颈效应。

如果是异构系统架构(整合了不同类型的处理器,如CPU和GPU,共享内存的处理器架构),CPU的内存管理单元(MMU)和GPU的输入输出内存管理单元(IOMMU)必须共享某些特性,如共享地址空间。

HSA定义了一种特殊的内存共享情况,即CPU的MMU和GPU的IOMMU有一个相同的可翻页的虚拟地址空间。

共享内存的替代方案是分布式内存和分布式共享内存,它们都有一系列类似的问题。

2      软件方面

在计算机软件中,共享内存是指:

1.         进程间通信(IPC)的一种方法,即同时运行的程序之间交换数据的一种方式。一个进程会在RAM中创建一个区域,其他进程可以访问。

2.         一种节约内存空间的方法,通过使用虚拟内存映射或在相关程序的明确支持下,将通常是数据副本的访问引导到单个实例上。这种方法最常用于共享库和原地执行(XIP)。

由于两个进程都可以像访问普通工作内存一样访问共享内存区域,所以这是一种非常快速的通信方式(与命名管道、Unix域套接字或CORBA等其他IPC机制相比)。另一方面,它的可扩展性较差,例如通信进程必须运行在同一台机器上(在其他IPC方法中,只有Internet域套接字--而不是Unix域套接字--可以使用计算机网络),而且如果共享内存的进程运行在不同的CPU上,而且底层架构不具有缓存一致性,必须注意避免出现由此引起的问题。

例如,通过共享内存的IPC用于Unix系统中应用程序和X服务器之间的图像传输,或者在Windows下COM库中CoMarshalInterThreadInterfaceInStream返回的IStream对象内。

动态库一般只在内存中保存一次,并映射到多个进程中,只有那些必须为各个进程定制的页面才会被复制,通常采用一种称为copy-on-write的机制,在尝试写的时候透明地复制页面,然后成功的写在私有副本上。

2.1    支持类Unix系统

POSIX提供了一个使用共享内存的标准化API,即POSIX Shared Memory。这使用了sys/mman.h中的函数shm_open。POSIX进程间通信(POSIX:XSI扩展的一部分)包括共享内存函数shmat、shmctl、shmdt和shmget。这使用了sys/shm.h中的shmget。BSD系统提供了 "匿名映射内存",可以被多个进程使用。

shm_open创建的共享内存是持久的。它一直留在系统中,直到被进程明确删除。这有一个缺点,就是如果进程崩溃并且没有清理共享内存,它就会一直存在,直到系统关闭。

POSIX还提供了mmap API,用于将文件映射到内存中;映射可以被共享,允许文件的内容作为共享内存使用。

基于2.6内核和更高版本的Linux发行版以RAM磁盘的形式提供/dev/shm作为共享内存,更确切地说,是作为一个公开可写目录(系统的每个用户都可以在其中创建文件的目录),存储在内存中。基于RedHat和Debian的发行版都默认包含了它。在内核配置文件中,对这种类型的RAM磁盘的支持是完全可选的。

2.2    对Windows的支持

在Windows上,可以使用CreateFileMapping和MapViewOfFile函数在多个进程中把文件的某个区域映射到内存中。

2.3    跨平台支持

一些C++库提供了可移植和面向对象的访问共享内存功能。例如,Boost包含Boost.Interprocess C++库,Qt提供了QSharedMemory类。

2.4    编程语言支持

除了C/C++之外,编程语言中也有对共享内存的本地支持。例如,PHP提供了一个创建共享内存的API,类似于POSIX函数。

3      参考

https://en.wikipedia.org/wiki/Shared_memory

https://www.geeksforgeeks.org/ipc-shared-memory/

https://apiacoa.org/teaching/big-data/smp.en.html

Shared memory共享内存

https://www.tutorialspoint.com/inter_process_communication/inter_process_communication_shared_memory.htm

https://opensource.com/article/19/4/interprocess-communication-linux-storage

https://www.it.uu.se/edu/course/homepage/os2/st10/handout-03b.pdf

Windows Linux

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:创龙TL437x-EVM评估板规格书详解
下一篇:【愚公系列】2022年01月 Java教学课程 55-字符的读取与写入
相关文章