繁体   English   中英

在不使用交换的情况下分配最大缓冲区

[英]Allocating largest buffer without using swap

在Linux下的C / C ++中,我需要分配一个大的(几千兆字节)内存块,以便存储连接到以太网端口的传感器的实时数据和大约110MB / s的流数据。 我想分配尽可能多的内存,以最大化我可以存储的数据序列的长度。 但是,我还需要确保不会进行磁盘交换,因为产生的延迟和磁盘访问带宽有限会导致传感器(非常有限)的缓冲区溢出。

确定要分配多少内存的最佳方法是什么? 我仅限于分配比报告的可用内存稍小的块,还是可以更直接地与linux虚拟内存管理器连接?

好吧,在linux下你可以使用mlock()/ mlockall()来保持物理内存中的地址范围并防止它被换出。 使用mlock的过程需要一些特权来执行此操作,“man mlock”具有详细信息。 我不确定最大的mlock'able块(它可能与看似“免费”的块有所不同),所以可能二进制搜索可能有所帮助(锁定范围,如果失败则减小区域的大小等等。)

另一方面,对于固态硬盘来说,110MB / s并不是真正的问题。 一个60GB的SSD,写入速度为280MB / s,在拐角处的成本约为200美元。 只需将传感器数据复制到一个小的写入缓冲区中,然后将其传输到SSD。

如果计算机系统专用于从传感器接收数据,则可以简单地禁用交换。 然后分配尽可能大的缓冲区,在系统中留下足够的内存仅用于基本工具。

如果你malloc的内存所需要的量,并在该速度写,你还是会被打到由于所有的页面错误(即虚拟内存的每个页面映射到物理内存,这也可能包括换出内存性能其他过程)。

为了避免这种情况,您可以在开始从传感器读取之前将整个分配的缓冲区memset为0,以便将所有需要的虚拟内存映射到物理内存。

如果您只使用可用的物理内存,则根本不应该进行交换。 使用更多将导致其他进程的内存交换到磁盘 - 如果这些进程空闲,它不应该造成任何问题。 如果它们处于活动状态(即偶尔使用它们的内存),则会发生一些交换 - 可能比硬盘驱动器带宽低得多。 您使用的内存越多,更多活动进程的内存将被换出,并且会发生更多的HD活动 - 此时,您可以使用的最大内存量具有良好的性能,这几乎是试验和错误的结果。

通过使用超过可用的物理内存,您肯定会导致内存写入速率的交换,并且没有办法避免这种情况。

确定要分配多少内存的最佳方法是什么?

由于虚拟内存的使用方式,不可交换的内核内存,几乎不可能确定应用程序可以访问多少已安装的内存。

我能想到的最好的是允许用户配置用于缓冲的内存量。

我仅限于分配比报告的可用内存略小的块,

报道的免费内存并不是真正的“免费物理内存”。 不幸。

或者我可以更直接地与linux虚拟内存管理器连接?

这可以通过使用自定义设备驱动程序,直接在内核空间中分配内存并通过mmap()提供对它的访问来完成。 一般不推荐,但适用于您的特殊情况。

但是,我还需要确保不会进行磁盘交换

随着Linux内核开发的步伐,知识变得非常快,所以我要说的就是我所说的。 您可以尝试使用以下内容:

  1. SysV共享内存。 它通常不会被交换。 man shmget

  2. tmpfs - 内存中的文件系统。 至少在早期的2.6内核中,内存被固定到RAM,因此无法交换。 要将它用作内存,请在tmpfs上创建一个文件,在文件中write()以强制实际分配内存,然后使用mmap()文件。

分配内存后,你可以

echo 0 > /proc/sys/vm/swappiness

要求内核更喜欢从缓存中回收内存而不是交换内存。

只需0.2美元

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM