#perl #memory #stack-size
#perl #память #размер стека
Вопрос:
Я генерировал случайные числа, используя модуль Crypt::Random для perl, который полагается на Math::Pari, интерфейс perl для Pari / GP, и получил эту ошибку при попытке сгенерировать 1,5-миллионное число:
C:UsersJlinneDocuments>perl -MCrypt::Random=makerandom_itv -E "say makerandom_itv(Lower => '10^1499999', Upper => '10^1500000')" > num_1500000.txt
PARI: *** the PARI stack overflows !
current stack size: 4.0 Mbytes
[hint] you can increase GP stack with allocatemem()
C:UsersRyanDocumentsPerl Scripts>perl scripts1.pl
"use" not allowed in expression at scripts1.pl line 6, at end of line
syntax error at scripts1.pl line 6, near "use Math::Pari
use Math::PariInit "
BEGIN not safe after errors--compilation aborted at scripts1.pl line 7.
Мой скрипт:
#!/usr/bin/env perl
use warnings;
use strict;
use feature 'say';
use Math::Pari
use Math::PariInit qw( primes=12000000 stack=1e8 );
use Crypt::Random
Я предполагал, что функция allocatemem() была функцией Math ::Pari, но это не так. Кто-нибудь знает, как изменить размер стека GP на 8,0 Мбайт с помощью скрипта по сравнению с однострочным? Спасибо.
Проблема со стеком до 1e 32
C:UsersJlinneDocumentsPerl Scripts>perl scripts1.pl > BIGINT1500000.txt
PARI: *** the PARI stack overflows !
current stack size: 0.0 Mbytes
[hint] you can increase GP stack with allocatemem()
Compilation failed in require at C:/Strawberry/perl/site/lib/Math/PariInit.pm line 26.
BEGIN failed--compilation aborted at scripts1.pl line 6.
Скрипт:
use warnings 'all';
use strict;
use feature 'say';
# use Math::Pari;
use Math::PariInit qw( stack=1e32 );
use Crypt::Random qw(makerandom_itv);
say makerandom_itv(Lower => '10^1499999', Upper => '10^1500000');
Комментарии:
1. (Кстати, вы пропускаете
;
в концеuse Math::Pari
.)2. Мой ответ ниже теперь содержит пример кода и был протестирован. Она работает так, как ожидалось.
Ответ №1:
Вам не нужно обращаться к allocatemem()
, которая указана как одна из функций, которые могут использоваться, но не поддерживаются напрямую, см. Это в Math::Pari.
Вместо этого из ИНИЦИАЛИЗАЦИИ в Math::Pari
Когда загружается Math::Pari, она проверяет переменные $Math::Pari::initmem и $Math::Pari::initprimes. Они определяют, до какого числа должен быть предварительно вычислен начальный список простых чисел, и насколько большой должна быть область для вычислений PARI (в байтах). (Эти значения имеют безопасные значения по умолчанию.)
Поскольку для установки этих значений перед загрузкой требуется либо блок BEGIN, либо отсрочка загрузки (использовать или требовать), может быть удобнее установить их с помощью Math::PariInit:
use Math::PariInit qw( primes=12000000 stack=1e8 );
Смотрите (короткую) страницу для Math::PariInit.
Полный пример
use warnings 'all';
use strict;
use feature 'say';
# use Math::Pari;
use Math::PariInit qw( stack=1e8 );
use Crypt::Random qw(makerandom_itv);
say makerandom_itv(Lower => '10^1499999', Upper => '10^1500000')";
Запуск script.pl > BIG_num.txt
генерирует 1.5Mb
файл с номером (через 11 минут).
Таким образом, размер стека устанавливается при компиляции. Смотрите первую ссылку для ее динамического изменения.
Комментарии:
1. Похоже, это не работает с модулями Math ::Pari, я добавил больше кода в сообщение.
2. @J.Linne Это все, что вы пробовали — однострочный? Это сложные среды, я бы посоветовал собрать небольшой скрипт, чтобы попробовать его — если вы этого не сделали. (Кстати, это не то, как вы загружаете параметры для модулей в однострочном.) Напишите скрипт, который загружает все необходимые вам модули, включая строку из моего ответа.
3. Я работаю в основном с однострочным, я помещаю команду one liner в скрипт и запускаю его, и все равно получаю ту же проблему с 3 миллионами цифр.
4. @J.Linne Вы вставили однострочную строку в какой скрипт? Сценарий оболочки? Опять же, я бы посоветовал вам написать небольшой скрипт на Perl, где вы вводите все необходимые
use ...
инструкции, включая ту, что приведена в моем ответе. Затем самый простой код, который вам нужен для теста. Затем вы можете вызвать ее из своего сценария оболочки вместо однострочной. (Я не могу сейчас протестировать запись.)5. ОПИСАНИЕ ^ use Math::PariInit принимает те же аргументы, что и use Math::Pari, с добавлением :primes=limit и :stack=bytes, которые указывают, до какого числа должен быть предварительно вычислен начальный список простых чисел, и насколько большой должна быть область для вычислений PARI. Аргументы primes и stack не могут быть указаны, если Math::Pari уже загружен.