简体   繁体   English

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

[英]Allocating largest buffer without using swap

In C/C++ under Linux, I need to allocate a large (several gigabyte) block of memory, in order to store real-time data from a sensor connected to the ethernet port and streaming data at about 110MB/s. 在Linux下的C / C ++中,我需要分配一个大的(几千兆字节)内存块,以便存储连接到以太网端口的传感器的实时数据和大约110MB / s的流数据。 I'd like to allocate the largest amount of memory possible, to maximise the length of data sequence that I can store. 我想分配尽可能多的内存,以最大化我可以存储的数据序列的长度。 However, I also need to make sure that there will be no disk-swapping, since the resulting delay and limited bandwidth of disk access causes the sensor's (very limited) buffer to overflow. 但是,我还需要确保不会进行磁盘交换,因为产生的延迟和磁盘访问带宽有限会导致传感器(非常有限)的缓冲区溢出。

What is the best way to determine how much memory to allocate? 确定要分配多少内存的最佳方法是什么? Am I limited to just allocating a slightly smaller block than the reported free memory, or can I interface more directly with the linux virtual memory manager? 我仅限于分配比报告的可用内存稍小的块,还是可以更直接地与linux虚拟内存管理器连接?

Well, under linux you can use mlock()/mlockall() to keep an adress range in physical memory and prevent it from being swapped out. 好吧,在linux下你可以使用mlock()/ mlockall()来保持物理内存中的地址范围并防止它被换出。 The process using mlock needs a couple of privileges to do so, "man mlock" has the details. 使用mlock的过程需要一些特权来执行此操作,“man mlock”具有详细信息。 I am not sure about the maximum mlock'able block (it might differ from what seems to be "free"), so probably a binary search could help (lock a range, if that fails reduce the size of the area etc..) 我不确定最大的mlock'able块(它可能与看似“免费”的块有所不同),所以可能二进制搜索可能有所帮助(锁定范围,如果失败则减小区域的大小等等。)

On the other hand, 110MB/s is not really a problem for a Solid-State-Drive. 另一方面,对于固态硬盘来说,110MB / s并不是真正的问题。 A 60GB SSD with 280MB/s write speed costs about $200 on the corner. 一个60GB的SSD,写入速度为280MB / s,在拐角处的成本约为200美元。 Just copy the sensor data into a small write buffer and stream that to the SSD. 只需将传感器数据复制到一个小的写入缓冲区中,然后将其传输到SSD。

If the computer system is dedicated to receiving data from your sensor, you can simply disable swap. 如果计算机系统专用于从传感器接收数据,则可以简单地禁用交换。 Then allocate as big buffer as you can, leaving enough memory in the system only for essential tools. 然后分配尽可能大的缓冲区,在系统中留下足够的内存仅用于基本工具。

If you malloc the needed amount of memory and write to it at that speed, you'll still get a performance hit due to all the page faults (ie mapping each page of virtual memory to physical memory, which also may include swapping out memory of other processes). 如果你malloc的内存所需要的量,并在该速度写,你还是会被打到由于所有的页面错误(即虚拟内存的每个页面映射到物理内存,这也可能包括换出内存性能其他过程)。

In order to avoid that, you could memset the entire allocated buffer to 0 before you start reading from the sensor, so that all the needed virtual memory is mapped to physical memory. 为了避免这种情况,您可以在开始从传感器读取之前将整个分配的缓冲区memset为0,以便将所有需要的虚拟内存映射到物理内存。

If you only use the available physical memory, you should suffer no swapping at all. 如果您只使用可用的物理内存,则根本不应该进行交换。 Using more would cause memory of other processes to be swapped to the disk - if these processes are idle, it shouldn't pose any problem. 使用更多将导致其他进程的内存交换到磁盘 - 如果这些进程空闲,它不应该造成任何问题。 If they're active (ie using their memory once in a while), some swapping would occur - probably in a much lower rate than the hard-drive bandwidth. 如果它们处于活动状态(即偶尔使用它们的内存),则会发生一些交换 - 可能比硬盘驱动器带宽低得多。 The more memory you use, more active processes' memory would be swapped out, and more HD activity would occur - at this point the maximal amount of memory you could use with decent performance is pretty much a result of trial and error. 您使用的内存越多,更多活动进程的内存将被换出,并且会发生更多的HD活动 - 此时,您可以使用的最大内存量具有良好的性能,这几乎是试验和错误的结果。

By using more than the physical memory available, you'll definitely cause swapping at the rate of memory writes, and there's no way to avoid that. 通过使用超过可用的物理内存,您肯定会导致内存写入速率的交换,并且没有办法避免这种情况。

What is the best way to determine how much memory to allocate? 确定要分配多少内存的最佳方法是什么?

Due to how virtual memory is used, non-swappable kernel memory, it is nearly impossible to identify how much of installed memory can be accessed by an application. 由于虚拟内存的使用方式,不可交换的内核内存,几乎不可能确定应用程序可以访问多少已安装的内存。

Best I can come up with is to allow user to configure how much memory to use for buffering. 我能想到的最好的是允许用户配置用于缓冲的内存量。

Am I limited to just allocating a slightly smaller block than the reported free memory, 我仅限于分配比报告的可用内存略小的块,

Reported free memory is not really "free physical memory." 报道的免费内存并不是真正的“免费物理内存”。 Unfortunately. 不幸。

or can I interface more directly with the linux virtual memory manager? 或者我可以更直接地与linux虚拟内存管理器连接?

That can be done by using a custom device driver, allocating memory directly in kernel space and providing access to it via mmap() . 这可以通过使用自定义设备驱动程序,直接在内核空间中分配内存并通过mmap()提供对它的访问来完成。 Generally not recommended, yet would works in specialized cases such as yours. 一般不推荐,但适用于您的特殊情况。

However, I also need to make sure that there will be no disk-swapping 但是,我还需要确保不会进行磁盘交换

At pace of the Linux kernel development, knowledge becomes obsolete quite fast, so take with grain of salt what I'm saying here. 随着Linux内核开发的步伐,知识变得非常快,所以我要说的就是我所说的。 You can try to play with the following: 您可以尝试使用以下内容:

  1. SysV shared memory. SysV共享内存。 It is generally not swapped. 它通常不会被交换。 See man shmget . man shmget

  2. tmpfs - in-memory file system. tmpfs - 内存中的文件系统。 The memory was pinned to RAM at least in early 2.6 kernels and thus was not swappable. 至少在早期的2.6内核中,内存被固定到RAM,因此无法交换。 To use it as memory, create a file on tmpfs, write() something into the file (to force the memory being actually allocated) and then mmap() the file. 要将它用作内存,请在tmpfs上创建一个文件,在文件中write()以强制实际分配内存,然后使用mmap()文件。

After you allocate your memory, you could 分配内存后,你可以

echo 0 > /proc/sys/vm/swappiness

To ask the kernel to prefer reclaiming memory from the cache instead of swapping. 要求内核更喜欢从缓存中回收内存而不是交换内存。

Just my $0.2 只需0.2美元

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

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