简体   繁体   English

C ++数组大小x86和x64

[英]C++ Array size x86 and for x64

Simple question, I'm writting a program that needs to open huge image files (8kx8k) but I'm a little bit confused on how to initialize the huge arrays to hold the images in c++. 一个简单的问题,我正在编写一个需要打开大图像文件(8kx8k)的程序,但是我对如何初始化大数组以将图像保存在c ++中感到有些困惑。

I been trying something like this: 我一直在尝试这样的事情:

long long SIZE = 8092*8092;     ///8096*8096
double* array;
array = (double*) malloc(sizeof(double) * SIZE);
if (array == NULL)
{
    fprintf(stderr,"Could not allocate that much memory");
}

But sometimes my NULL check does not catch that the array was not initialized, any idea why? 但是有时我的NULL检查不能捕获未初始化的数组,为什么?

Also I can't initialize more that 2 or 3 arrays, even when running in a x64 machine with 12 GB of RAM, any idea why? 另外,即使在具有12 GB RAM的x64机器上运行,我也不能初始化超过2个或3个数组。

I would really wish not to have to work with sections of array instead. 我真的希望不必使用数组的各个部分。 Any help is welcome. 欢迎任何帮助。

Thanks. 谢谢。

You're not running into an array size problem. 您没有遇到数组大小问题。 8K*8K is merely 64M. 8K * 8K仅为64M。 Even 64M doubles (sizeof==8) are not an issue; 即使是64M的双打(sizeof == 8)也不是问题。 that would require a mere 512 MB. 仅需要512 MB。 Now, a 32 bit application (no matter where it's running) should be able to allocate a few of them. 现在,一个32位应用程序(无论它在何处运行)都应该能够分配其中的一些。 Not 8, because the OS typically needs to reserve some space for itself (often slightly over 2GB) and sometimes not even 3 when memory is fragmented. 不是8,因为操作系统通常需要为其自身保留一些空间(通常略大于2GB),有时在内存碎片时甚至不需要3。

The behavior of "malloc failed but didn't return NULL" is a Linux configuration bug, fixed by # echo 2 > /proc/sys/vm/overcommit_memory “ malloc失败但未返回NULL”的行为是Linux配置错误,已通过# echo 2 > /proc/sys/vm/overcommit_memory修复

malloc() does not initialize memory, it just reserves it. malloc()不会初始化内存,它只是保留它。 You will have to initialize it explicitly, eg via memset() from string.h: 您将必须显式初始化它,例如通过string.h的memset()进行初始化:

array = (double*) malloc(SIZE * sizeof(double));
if (array) memset(array, 0, SIZE * sizeof(double));

However, in C++ you should use new instead of malloc : 但是,在C ++中,应使用new而不是malloc

double* array = new double[SIZE];
if (!array) {
    cerr << "Could not allocate that much memory" << endl;
}
for (int i=0; i<SIZE; i++) array[i] = 0.0;

Regarding size: each such array is 512 MB. 关于大小:每个这样的阵列为512 MB。 Are you positively sure you need double precision (which means the image has 64-bit pixel depth)? 您是否确定需要双精度(这意味着图像具有64位像素深度)? Maybe a float would suffice? 也许花车就足够了? That would halve the memory footprint. 那将使内存占用减少一半。

You might be running into a 2GB per-process address space limit if you are running a 32bit operating system. 如果运行的是32位操作系统,则可能会遇到2GB的每个进程地址空间限制。 With a few hundred MBs of system libs and other stuff, and 2 or 3 arrays of 512MB each, that will give 2GB easily. 拥有数百MB的系统库和其他内容,以及2或3个512MB的阵列,将轻松获得2GB。 A 64bit OS would help you there. 64位操作系统将为您提供帮助。

Are you compiling your application as a 32-bit application (the default in Visual Studio, if that's what you're using), or as a 64-bit application? 您是将应用程序编译为32位应用程序(如果使用的是Visual Studio中的默认设置)还是64位应用程序? You shouldn't have troubles if you build it as a 64-bit app. 如果将其构建为64位应用程序,则不会有麻烦。

malloc allocates (reserves memory and returns a pointer), calloc initializes (writes all zeros to that memory). malloc分配(保留内存并返回一个指针),calloc初始化(将全零写入该内存)。

Seems to be that you have no continuous memory block of such size (~500Mb) in C runtime heap. 似乎在C运行时堆中没有这样大小的连续内存块(〜500Mb)。 Instead of copying file into memory try to map image into a processes address space. 不要将文件复制到内存中,而是尝试将映像映射到进程地址空间中。 You could map only necessary parts of the file. 您只能映射文件的必要部分。

Just as a side note: although you don't want to bother about the whole image not being in memory at once, there are reasons not to do it. 正如一个侧面说明:虽然你不想理会整个图像在内存不是马上,还有理由不这样做。 Maybe think about an abstraction that allows you to keep only the currently needed chunk in memory. 也许考虑一个抽象,它允许您仅将当前所需的块保留在内存中。 The program code then can be written as though ignorant of the memory issues. 然后可以编写程序代码,就好像忽略内存问题一样。

I would really wish not to have to work with sections of array instead. 我真的希望不必使用数组的各个部分。 Any help is welcome. 欢迎任何帮助。

Have you looked into memory-mapped files? 您是否研究过内存映射文件?

Yep, sounds a lot like heap fragmentation, as Kirill pointed out . 是的,就像基里尔指出的那样 ,听起来很像堆碎片。 See also: How to avoid heap fragmentation? 另请参阅: 如何避免堆碎片化?

i suggest using compression. 我建议使用压缩。 decompress part of it which you need to process in your code whenever, and compress it after the part done. 解压缩您需要在代码中随时处理的部分,并在完成部分后对其进行压缩。

2nd proposal: write code to overload memory pointer "operator+" and "operator-" so you could use non-continuous memory buffers. 第二个建议:将代码写入过载内存指针“ operator +”和“ operator-”,以便可以使用非连续的内存缓冲区。 use smaller memory buffers make your code more stable than a continuous larger one. 使用较小的内存缓冲区可使代码比连续的较大缓冲区更稳定。 i had experienced it and had written some operator-overloading, see http://code.google.com/p/effoaddon/source/browse/trunk/devel/effo/codebase/addons/mem/include/mcur_i.h for the example. 我已经经历过并写了一些运算符重载,请参阅http://code.google.com/p/effoaddon/source/browse/trunk/devel/effo/codebase/addons/mem/include/mcur_i.h例。 when i test 47G malloc()ed system memory on a x86_64, i allocated just 1G per malloc() call, so i allocated 47 memory blocks in total. 当我在x86_64上测试47G malloc()系统内存时,每个malloc()调用仅分配1G,因此我总共分配了47个内存块。 EDIT: while if i tried to allocate as much as possible by using just one malloc(), i would only get 30G on a 48G system, say less than 70%, that's because larger buffer per malloc() requested, much more managemental memory consumed by the system/libc itself, you know, I called mlock() to prevent the allocated memory from being swapped out to the disk. 编辑:虽然如果我尝试仅使用一个malloc()分配尽可能多的内容,但我在48G系统上只能获得30G的存储空间,比如说不到70%,那是因为每个malloc()请求的缓冲区更大,管理内存也更多您知道,由系统/ libc本身消耗的内存被称为mlock(),以防止分配的内存被换出到磁盘上。

3rd one: try posix file mapping, map to memory per image. 第三个:尝试posix文件映射,每个图像映射到内存。

Btw: call malloc() is more stable than new() though writing c++, because when memory got stressed, new() is prone to trow exceptions instead of returning NULL. 顺便说一句:尽管编写c ++,调用malloc()比new()更稳定,因为当内存紧张时,new()倾向于抛出异常,而不是返回NULL。

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

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