R функция mcfork
является лишь оболочкой для системного вызова fork
(КСТАТИ, страница человека говорит, что этот вызов сам по себе является оберткой к clone
)
Я создал простой C++ программы, чтобы проверить поведение fork
«s :
#include <stdio.h>
#include <unistd.h>
#include<vector>
int main(int argc, char **argv)
{
printf("--beginning of program\n");
std::vector<std::vector<int> > l(50000, std::vector<int>(50000, 0));
// while (true) {}
int counter = 0;
pid_t pid = fork();
pid = fork();
pid = fork();
if (pid == 0)
{
// child process
int i = 0;
for (; i < 5; ++i)
{
printf("child process: counter=%d\n", ++counter);
}
}
else if (pid > 0)
{
// parent process
int j = 0;
for (; j < 5; ++j)
{
printf("parent process: counter=%d\n", ++counter);
}
}
else
{
// fork failed
printf("fork() failed!\n");
return 1;
}
printf("--end of program--\n");
while (true) {}
return 0;
}
Во-первых, программа выделяет около 8 ГБ данных в кучу. Затем он запускает 2^2^2 = 8 детей через вызов fork и ждет, чтобы его убил пользователь, и вводит бесконечный цикл, который легко обнаружить в диспетчере задач.
Вот мои наблюдения:
- Для развилки, чтобы добиться успеха, вы должны иметь по крайней мере 51% свободной памяти в системе, но это включает в себя обмен. Вы можете изменить это, отредактировав файлы proc
/proc/sys/vm/overcommit_*
.
- Как и ожидалось, ни один из детей не получает больше памяти, поэтому эта свободная память на 51% остается свободной на протяжении всего курса программы, и все последующие вилки также не терпят неудачу.
- Память делится между вилками, поэтому она восстанавливается только после того, как вы убили последнего ребенка.
фрагментация памяти проблема
Вы не должны беспокоиться о каком-либо слое фрагментации памяти относительно к вилке. Фрагментация памяти R здесь не применяется, поскольку fork работает в виртуальной памяти. Вы не должны беспокоиться о фрагментации физической памяти, поскольку практически все современные операционные системы используют виртуальную память (что, следовательно, позволяет использовать swap). Единственной фрагментацией памяти, которая может возникнуть, является фрагментация пространства виртуальной памяти, но пространство виртуальной памяти AFAIK на Linux составляет 2^47, что является более чем огромным, и на протяжении многих десятилетий у вас не должно быть проблем с поиском непрерывных областей любой практический размер.
Резюме:
Убедитесь, что на подкачку затем физическую память, и до тех пор, пока ваши вычисления не на самом деле нужно больше памяти, то есть в памяти, вы можете mcfork
их столько, сколько вы хотите.
Или, если вы готовы рисковать стабильностью (голодом памяти) всей системы, попробуйте echo 1 >/proc/sys/vm/overcommit_memory
как root на linux.
Или еще лучше: (более безопасно)
echo 2 >/proc/sys/vm/overcommit_memory
echo 100 >/proc/sys/vm/overcommit_ratio
Вы можете прочитать больше о overcommiting здесь: https://www.win.tue.nl/~aeb/linux/lk/lk-9.html
R требует последовательных блоков памяти. Вы перезапустили и попытались повторно запустить с минимальными данными? –
Я попытался с другим экземпляром с удвоенной памятью, это решило проблему ... Мне все же хотелось бы понять это лучше, хотя, поэтому я оставлю вопрос открытым. –