Почему вычисление 1 / (n * log (n) - n) ломает компьютер? - PullRequest
0 голосов
/ 06 ноября 2018

Недавно я наткнулся на проблему Вольфрам говорит, что сумма расходится, но Mathematica дает числовое значение . Он говорит, что 1/(n * log(n) - n) не суммируемо (или не сходится математически, чтобы быть правильным). Интересно то, что мы все еще можем попытаться подсчитать сумму численно, несмотря на то, что она «не суммируется». Mathematica дает числовой ответ ~ 6.1.

OK. Я думаю, давайте попробуем воспроизвести это число (или что-то подобное) в PHP-сценарии суммирования этой серии. Мой код был:

$formula = function ($n) {return 1/($n * log($n) - $n);};
$n=2;
$sum=0;

while(true) {
    $term_n = $formula($n);
    $sum += $term_n;
    if ($n++ % 100000 == 0) {
        if ($sum > 5.8)
            usleep(1000);
        echo "n=".number_format($n-1)."; sum={$sum}; error={$term_n}\n";
    }
}

Мой алгоритм вычислял ответ до 5.866, и затем происходила одна из двух вещей:

  1. либо Ubuntu зависал / зависал
  2. Или Linux убил мой процесс сценария вычисления

Это произошло после примерно 34 миллионов итераций.

Позже я проверил, как изменяется нагрузка на процессор в связи с вычислением большего количества последовательных терминов.

Теперь интересная часть: примерно на 22 миллионах итераций ядра испытывали трудности с переключением задач между собой: enter image description here

Позже, примерно за 33 миллиона итераций, ядра достигли точки невозврата - они вообще отказались работать: enter image description here

Вопрос в том - Что такого особенного в сумме 5.866, что она дает сбой компьютеру? - учитывая тот факт, что ни число итераций N не очень велико (всего 34 миллиона), ни N- очень маленький термин (всего 1.7E-9) - поэтому нет причин для сингулярности.

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Я сузил проблему до ее корней - чем больше вызовов функций выполняется в скрипте, тем больше утечек памяти. И не имеет значения, какие функции (ы) вызываются - пользовательские, sin (), log () или min (,) или что-то еще. Поэтому я подозреваю, что это ошибка в ядре PHP, которая возникает при определенных условиях / ОС ядра.

Тестовый код:

define('AMOUNT', 2000000);

if ($argc == 1)
    for ($i=AMOUNT; $i <= 3*AMOUNT; $i+=AMOUNT) 
        shell_exec('php ' . __FILE__ . " {$i}");
else 
    for ($i=0; $i < $argv[1]; $i++)
        sin(1);
    /*
    Change line above into something without a function call to stop memory leak :
    $x++; // for example
    */

создает такой график утечки памяти:

enter image description here

0 голосов
/ 06 ноября 2018

Просто предположение, но звучит так, будто компьютеру не хватает памяти. Ваш сценарий явно не выделяет какую-либо память, но, возможно, ваша версия PHP содержит ошибку и каким-то образом теряет память.

Если свободная память была исчерпана, это может привести к выходу из строя работающей ОС или к тому, что она убьет ваш сценарий, чтобы защитить себя.

Если система начала интенсивно использовать пространство подкачки для компенсации, это на мгновение остановит ваш скрипт, вызывая колебания в графиках ЦП, которые вы наблюдаете.

...