Кажется, это очень распространенная проблема, но я до сих пор не нашел однозначного ответа.
У меня есть доступ к серверу, который работает под Linux, имеет 16 ГБ оперативной памяти и 16-ядерный (64-битный) процессор
(/ proc / cpuinfo выдает «Intel (R) Xeon (R) CPU E5520 @ 2,27 ГГц»). Тем не менее, ядро
32 бита (uname -m дает i686). Конечно, у меня нет root-доступа, поэтому я не могу изменить
тот.
Я запускаю C ++ — программу, которую я написал, которая выполняет некоторые вычисления, требующие памяти, поэтому я
Мне нужна большая куча — но всякий раз, когда я пытаюсь выделить более 2 ГБ, я получаю badalloc,
хотя ulimit возвращает «безлимитный».
Для простоты, скажем так, моя программа такова:
#include <iostream>
#include <vector>
int main() {
int i = 0;
std::vector<std::vector<int> > vv;
for (;;) {
++i;
vv.resize(vv.size() + 1);
std::vector<int>* v = &(vv.at(vv.size() - 1));
v->resize(1024 * 1024 * 128);
std::cout << i * 512 << " MB.\n";
}
return 0;
}
После компиляции с g ++ (без флагов), вывод будет:
512 MB.
1024 MB.
1536 MB.
2048 MB.
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Aborted
Насколько я понимаю, это ограничение 32-битных систем, видимо потому, что 32-битный указатель
может содержать 2 ^ 32 разных адресов (Прав ли я, если я скомпилирую ту же программу?
на том же сервере, но этот сервер работает с 64-битным ядром, чем программа может выделить более
2 Гб?)
Это не вопрос того, является ли выделенная память непрерывной, если я нарежу тоньше
В примере программы возникает та же проблема, и в моей реальной программе нет больших блоков
память, просто много маленьких.
Итак, мой вопрос:
Что я могу сделать? Я не могу изменить ОС, но, конечно, я могу изменить свой исходный код,
использовать различные параметры компилятора и т. д. …
но мне нужно больше, чем 2 ГБ памяти, все сразу, и нет никакого очевидного способа дальнейшей оптимизации
алгоритм, используемый программой.
Если ответ — «нет», было бы хорошо узнать это.
Спасибо,
Lukas
Если вам нужна память все сразу, нет, на самом деле нет способа сделать это без перехода на 64-битное ядро (что, да, позволило бы вам выделить больше памяти в одном процессе)
Тем не менее, если вам не нужна память сразу, а просто с быстрым доступом, вы всегда можете перенести части памяти в другой процесс.
Например, это может сработать, сохранив данные в другом процессе, и ваш процесс временно отобразит общую память из этого процесса в свое собственное пространство памяти, когда это необходимо. Он все еще будет храниться в памяти, но при переключении диапазона памяти у вас будут некоторые накладные расходы. Если допустимые издержки приемлемы или нет, это будет зависеть от вашей схемы доступа к памяти.
Это не очень прямой подход, но без изменения ядра, чтобы дать вам 64-битное адресное пространство, кажется, что вы в некотором роде.
РЕДАКТИРОВАТЬ: Вы можете поднять ограничение чуть выше 2 ГБ, перенастроив ядро, но это только означает, что вместо этого вы достигнете жесткого предела. Кроме того, это потребует root-доступа.
Ответ ясен «Нет». Если вы не можете изменить ОС, вы не можете поднять лимит. Ограничение применяется ко всему процессу, и, очевидно, ни одно выделение не может превышать ограничение по каждому процессу.
В зависимости от параметров, используемых для компиляции ядра, ограничение может быть выше 2 ГБ, но, безусловно, будет менее 4 ГБ. Но я думаю, что перекомпиляция ядра также считается «изменением ОС».
Увидеть это обсуждение
И да, на 64-битной ОС этот предел исчезнет.