如何在64位Linux系统中使用new运算符动态分配大内存,比如10G?

9

我需要使用C++的new运算符为一个特殊应用程序动态分配较大的浮点数数组,例如10G。代码在64-ubuntu-14.04 Linux操作系统上运行,具有64G内存。 当我将内存请求设置为约7G时,1879048192x4/(1024x1024x1024)=7G(float占用4个字节),就像这样:

float * data; 
data = new float[1879048192];

程序运行良好,但当我尝试将请求增加到10G时,我遇到了一个what(): std::bad_alloc的错误。 我还尝试使用malloc()代替new运算符:
data =(float*)malloc(1879048192*sizeof(float));

但是要获得相同的结果。我的 ulimit -a 是这样的:
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 514689
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 514689
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

有人可能会说,可能没有10G的连续内存可以分配,但我关闭了所有其他进程,总内存为64G。我想知道是否可以获取这个更大的数组,以及如何获取。Linux是否限制了动态分配的最大数量?在哪里以及如何解决?


评论不适合进行长时间的讨论;此对话已被移至聊天室 - Taryn
1
糟糕,又出事了。 - Paul
常量1879048192和1879048192 * sizeof(float)的类型是什么?您将如何编写10G常量?尝试使用带LL后缀的long long常量(https://dev59.com/mnM_5IYBdhLWcg3wQQpd#1458934):1879048192LL;或者在long long类型的变量中计算大小而不使用大常量 - osgx
1个回答

2
我尝试使用newmalloc都没有问题。我的系统运行Ubuntu 15.04,内存为16G。
但是,如果我要使用这些内存,我需要非常小心地选择用于索引数据数组的变量类型。
例如,下面的程序只使用long intfloat会出现不良反应,因为long int的最大值为2^31,而10Gi的数组长度将超过2^31。另外,浮点数每次只增加1.016777216.0。对于双精度浮点数,可以在这里使用长整数索引,因为数组较短。
使用use10G.c++。
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv){
  long long int ten = 10;
  long long int megi = 1024*1024;
  long long int gigi = 1024*megi;
  long long int asize = (ten*gigi)/((long int) sizeof(double));
  double * data = new double[asize];
  long long int i=2;
  printf("A double is %zd bytes\n", (size_t) sizeof(double));
  printf("Array size is %lli \n", asize);
  data[0]=0.0;
  data[1]=1.0;
  while (i<asize) {
    data[i]=data[i-1]+1.0;
    ++i;
  }
  printf("%lf\n", (double) data[asize-1]);
  printf("success\n");
  exit(EXIT_SUCCESS);
}

A double is 8 bytes
Array size is 1342177280 
1342177279.000000
success

你是对的!看来我在索引方面犯了一个愚蠢的错误,非常感谢!谢谢! - changingivan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接