OberonCore
https://forum.oberoncore.ru/

Узнать размер стека
https://forum.oberoncore.ru/viewtopic.php?f=2&t=6539
Страница 1 из 1

Автор:  snark [ Понедельник, 13 Январь, 2020 16:28 ]
Заголовок сообщения:  Узнать размер стека

дана программа вывода чисел Фибоначчи

MODULE Fibonacci;
IMPORT StdLog;
PROCEDURE Do*;
VAR
a, b, c, i, n: INTEGER;
BEGIN
a := 0;
b := 1;
n := 9;
FOR i := 0 TO n DO
c := b;
b := a + b;
a := c;
StdLog.Int( c );
END;
END Do;
END Fibonacci.

все просто-выводит 10 чисел.Если однако убрать строчку n := 9; то программа начнет выводить бесконечное число цифр пока блекбох не зависнет с надписью "NOT RESPONDING".
Ясное дело что отведенный операционной системой стек оказался переполненым и ОС аварийно остановила программу.Вопрос: как узнать/вычислить сколько чисел максимально может выдать программа не зависнув?

Автор:  Sergej Durmanov [ Понедельник, 13 Январь, 2020 18:16 ]
Заголовок сообщения:  Re: Узнать размер стека

А причем здесь стек?

Автор:  Иван Денисов [ Понедельник, 13 Январь, 2020 19:03 ]
Заголовок сообщения:  Re: Узнать размер стека

Блэкбокс никогда не инициализирует переменные базовых типов внутри процедур.
Это важное свойство для скорости выполнения программ, а также для обучения начинающих программистов.
Поэтому ваша обязанность присвоить n какое-то значение.
Обнаружить такие ошибки в коде помогает команда Инфо -> Анализировать модуль

Вложение:
Снимок экрана от 2020-01-13 23-03-02.png
Снимок экрана от 2020-01-13 23-03-02.png [ 45.7 КБ | Просмотров: 7423 ]


В вашем случае n может быть очень большим, так как содержит "мусор" из оперативной памяти.
Поэтому программа выполняется очень долго. Но что хуже — её поведение не определено... ведь n может быть и отрицательным числом.

Автор:  Иван Денисов [ Понедельник, 13 Январь, 2020 19:22 ]
Заголовок сообщения:  Re: Узнать размер стека

Теперь, если понять ваш вопрос иначе...

Начнем с того, что Блэкбокс не завис, а продолжает выполнять ваше задание.
Но Windows думает, что он завис, поэтому показывает вам сообщение.
Он так думает, потому что Блэкбокс перестал отвечать на системные сообщения.

Чтобы ББ отвечал на них, и иногда обновлял интерфейс, надо в ваш цикл вставить вызов вот такой процедуры:
Код:
   PROCEDURE ProcessMessages;
      VAR msg: Win.MSG; res: INTEGER;
   BEGIN
      WHILE Win.PeekMessage(msg, 0, 0, 0, Win.PM_REMOVE) # 0 DO
         res := Win.TranslateMessage(msg); res := Win.DispatchMessageA(msg)
   END END ProcessMessages;

Спасибо Штирлицу, что когда-то показал мне такое решение: viewtopic.php?f=31&t=1937&p=39240#p39240

Получится вот такой код:

Код:
MODULE Fibonacci;

IMPORT StdLog, Win := WinApi;

PROCEDURE ProcessMessages;
   VAR msg: Win.MSG; res: INTEGER;
BEGIN
   WHILE Win.PeekMessage(msg, 0, 0, 0, Win.PM_REMOVE) # 0 DO
      res := Win.TranslateMessage(msg); res := Win.DispatchMessageA(msg)
END END ProcessMessages;

PROCEDURE Do*;
VAR
   a, b, c, i, n: INTEGER;
BEGIN
   a := 0;
   b := 1;
   n := 900000;
   FOR i := 0 TO n DO
      c := b;
      b := a + b;
      a := c;
      StdLog.Int( c );
      IF i MOD 10000 = 0 THEN
         ProcessMessages
      END
   END;
END Do;

END Fibonacci.


Однако более правильное решение часто - это разбить вычисления на порции и организовать в очередь рекурсивно устанавливающихся событий.
Этот вопрос обсуждался тут:
viewtopic.php?f=1&t=130

Автор:  Trurl [ Понедельник, 13 Январь, 2020 19:42 ]
Заголовок сообщения:  Re: Узнать размер стека

Иван Денисов писал(а):
В вашем случае n может быть очень большим, так как содержит "мусор" из оперативной памяти.
Поэтому программа выполняется очень долго.

Каким бы большим оно не было, это 32-битное число, программа не должна выполнятся слишком долго. Здесь дело в том, что слишком много пишется в журнал.

Автор:  Иван Денисов [ Понедельник, 13 Январь, 2020 19:46 ]
Заголовок сообщения:  Re: Узнать размер стека

Сочетание двух факторов ;)

Сложность тела цикла + Число повторений цикла

А сложность может быть большой и без вывода в журнал.

Автор:  ЯрославЗлой [ Четверг, 09 Июль, 2020 09:48 ]
Заголовок сообщения:  Re: Узнать размер стека

Trurl писал(а):
Иван Денисов писал(а):
В вашем случае n может быть очень большим, так как содержит "мусор" из оперативной памяти.
Поэтому программа выполняется очень долго.

Каким бы большим оно не было, это 32-битное число, программа не должна выполнятся слишком долго. Здесь дело в том, что слишком много пишется в журнал.

А можно по подробней в этом плане?

Автор:  Trurl [ Суббота, 11 Июль, 2020 13:12 ]
Заголовок сообщения:  Re: Узнать размер стека

Для любого 32-битного числа (кроме одного) собственно вычисления займут не более нескольких секунд. Но запись в журнал такого количества информации, а затем её отображение - большая нагрузка на систему.

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/