我想在Linux / C / C ++中使用一个任意大的缓冲区

基本上我想要一个任意大的堆栈。 我知道这是不可能的,但我能为它留出几个TB的虚拟地址空间吗? 我希望能够从头开始,并根据需要走到缓冲区,Linux可以根据需要从物理内存中引入页面。 是这样的可能吗? 它会像malloc缓冲区一样具有相同的性能吗? 有没有办法向Linux发出信号:一旦你popup堆栈,你就完成了内存的设置?

编辑:我想要这个,因为我想优化一个recursion/并行algorithm,在每次调用分配大量的内存。 Malloc对我来说太慢了,我不希望所有的线程在malloc的锁里面互相绊倒。 所以基本上它将是我自己的运行时间堆栈和真正的堆栈(每个线程一个)。

实际上,只要运行时间足够大就足够了。 有没有办法知道/确保堆栈的大小? 在64位地址空间中,有足够的空间让几个线程堆栈分配千兆字节的数据。 那可行吗?

它看起来像pthread_attr_setstacksize可以为新线程工作,但是这并没有什么帮助,如果你可以从任何线程调用…

Solutions Collecting From Web of "我想在Linux / C / C ++中使用一个任意大的缓冲区"

您可以使用mmap()MAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE创建这样的分配 MAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE MAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE标志。 当你想释放它回到系统,使用munmap()

请注意,如果内存不足以满足您的实际使用,唯一的方法就是您的进程接收到一个SIGSEGV – 但是这是与寻求比可用内存大得多的巨大映射的领域来的。

那么,如果你想要一个大堆栈,你总是可以改变ulimit -s 。 它可以是非常大的,至少在64位平台上。

如果您使用匿名空间进行映射,则在您触摸它之前,实际上不会分配物理页面。 你需要设置vm_overcommit或有足够的交换(除非你有这么多的物理RAM)。 当然,当你要求大量的内存时, mmap的匿名空间正是malloc所做的。

你可以告诉Linux你用madvise完成了页面。 如果你打电话给MADV_DONTNEED ,那么Linux将丢弃这些页面 ,下一次尝试访问这些页面时应该填充它们。

首先,大小(或者new或者在堆栈上创建)的内存几乎肯定会导致一个std::bad_alloc错误,因为你试图在连续的内存中创建它 – 而且你最肯定的是由于碎片化,没有那么多不间断,连续的内存。

如果你使用一个std::容器像deque或者一个容器适配器就像一个stack (没有连续内存的东西 – 即不是一个向量),那么它将使用可扩展的堆内存。 这会让你围绕bad_alloc错误。

所以,它可能,但不要尝试使内存连续 – 如果你允许使用一个std::容器/适配器。

PS:如果你需要大的内存空间,你可以考虑使用一个动态分配的缓冲区列表( malloc ed指针),它们的大小足够大,可以使用,但又足够小,可能不会触发bad_alloc异常。

不要忘记,资源总是受物理约束的限制:宇宙中的原子数量可能是有限的…所以任意大的缓冲区不能严格意义上存在…

但是,您可以使用Linux mmap系统调用将文件的一部分视为虚拟内存段。 如果它非常大(大于RAM),则会出现性能问题。 考虑用madvise (&也许是readahead )系统调用来调整它。

也许甚至使用GCC __bultin_prefetch函数可能是有用的(但我相信madvise更相关)。

如果你真的有一个TB的堆栈,调整你的应用程序将是非常重要的。 学习使用oprofile 。 我希望你有一个强大的机器!

这对于调用堆栈来说还不够(它可能是有限的,例如通过setrlimit …)另请参见sigaltstack (用于信号传递的堆栈)。

但是你真的想要达到什么目的? 很大的调用堆栈对我来说似乎是可疑的…或者是你的堆栈不是调用堆栈?

 Create stack using two queues in that way you can have variable length of stack, which will increase as you require. implementing stack using two queues initially q1 is full and q2 empty 1] tranfer elements from q1 to q2 till last element left in q1 2] loop till q2 is not empty deque element from q2 and again push in q2 till last element is left in q2 transfer this last element in q1 reduce size of q2 by 1 3]finally q1 contains all elements in reverse order as in stack eg 1] q1 = 1 2 3 4 q2 = 2] 3 deques till last element left in q1 q1 = 4 q2 = 1 2 3 3] deque and again queue q2 till last element left q1 = 4 q2 = 3 1 2 4] deque q2 and queue q1 q1 = 4 3 q2 = 1 2 5] again deque and queue q2 till last element left q1= 4 3 q2= 2 1 6] queue q1 q1= 4 3 2 7] queue last element of q2 to q1 q1= 4 3 2 1