OberonCore
https://forum.oberoncore.ru/

Что делать с LEN в амд64?
https://forum.oberoncore.ru/viewtopic.php?f=127&t=6690
Страница 1 из 1

Автор:  adimetrius [ Воскресенье, 06 Декабрь, 2020 14:48 ]
Заголовок сообщения:  Что делать с LEN в амд64?

Коллеги, в нашем языке массивы определяются так:
Language Report писал(а):
An array is a structure consisting of a number of elements which are all of the same type, called the element type. The number of elements of an array is called its length. The elements of the array are designated by indices, which are integers between 0 and the length minus 1.

т.е. ограничений на размер массивов не накладывается напрямую; косвенно - максимальное целое, представимое в языке - MAX(LONGINT).

Но процедура LEN Определяется вот так:
Language Report писал(а):
LEN(v, x)
Argument type: v: array; x: integer constant
Result type: INTEGER
Function: length of v in dimension x (first dimension = 0)

LEN(v)
Argument type: array type
Result type: INTEGER equivalent to LEN(v, 0)

Argument type: String
Result type: INTEGER
Function: length of string (not counting 0X)


Таким образом, LEN может работать только с массивами <MAX(INTEGER).

На базе и386 не было практического смысла ставить этот вопрос. Но на базе амд64 - нужно прояснить. Ведь вполне можно вообразить на практике массив с >MAX(INTEGER) байт. И уж тем более - для системных целей POINTER [untagged] TO ARRAY OF BYTE, который можно использовать чтобы хоть ко всему адресному пространству обращаться.

Что же делать с LEN?

Вариант А: переопределить, что она возвращает LONGINT. Слабость этого варианта:
VAR len: INTEGER;
len := LEN(a); (* Ошибка: требуется явное приведение типов *)

Ну, можно потребовать, чтобы все пользовались приведением:
len := SHORT(LEN(a));
Но это неудобно в подавляющем большинстве употреблений. И кроме того, потребует правки прежних программ при переносе на амд64.

Вариант Б: пусть возвращает INTEGER для фиксированных массивов малого размера, и LONGINT для открытых массивов и для больших фиксированных. Слабость - открытые массивы часто используются в параметрах:
PROCEDURE P (IN a: ARRAY OF BYTE);
VAR len: INTEGER;
len := LEN(a) (* Ошибка, даже если фактический параметр - малый фиксированный массив *)

Вариант В: пусть возвращает INTEGER, но дополнить определение: если значение выходит за ОДЗ INTEGER, происходит аварийный останов. (Это эквивалентно тому, чтобы LEN возвращала LONGINT, но компилятор вместо LEN() везде вставлял SHORT(LEN()) с принудительной проверкой ОДЗ.) Такой вариант удобен для подавляющего большинства употреблений; и не потребует правки прежних программ при переносе на амд64.
Но как тогда узнавать длину больших массивов?
1) ввести LONGLEN? Плюс этого варианта - все чисто, нет "особых случаев" (см. п. 3). Минус - новое имя в Сообщении о языке.
2) ввести SYSTEM.LEN?
3) использовать LONG(LEN())?
VAR long: LONGINT;
long := LONG(LEN(a))
В этом примере кажется неуместной явная запись LONG(), поскольку и так подразумевается неявное приведение INTEGER к LONGINT даже при
long := LEN(a)
А вот в таком - вполне уместна:
long := LONG(LEN(a)) - 1;
Поскольку в
long := LEN(a) - 1;
в вычитании участвуют два INTEGER, и должна проводиться проверка ОДЗ.
Минус этого варианта - введение особого случая: обычно LEN возвращает INTEGER, но иногда, если "снаружи" оказалось LONGINT - то возвращает LONGINT.

Есть, конечно, и Вариант Г: ограничить длину массива числом MAX(INTEGER).

Какие есть соображения или предложения по теме, коллеги?

Автор:  Илья Ермаков [ Воскресенье, 06 Декабрь, 2020 15:06 ]
Заголовок сообщения:  Re: Что делать с LEN в амд64?

На первый взгляд, я бы ограничил длину массива размером INTEGER. Не возникает проблем.

Большего размера массивы не будут ни глобальными переменными, ни стековыми.
А что-то специфическое большое и в куче в специфическом случае и через untagged можно обработать.

Но: при выходе в 64 бит и на современных объёмах ОЗУ возникают и новые возможности для мат. приложений.
Засунуть прямо в память что-нибудь - и там обработать...

Но на но: что-то практическое всё равно занимает от 8 байт, а практически-интересное - ещё и многомерное.
У вас даже ARRAY 2^31 OF REAL - уже 16 Гб ОЗУ.

Так что LEN(): INTEGER для любых интересных мат. применений с большими ОЗУ тоже хватать должно за глаза.

Так что приходим к тому, что ограничивать длину массивов по одному измерению порогом 2^31.

Автор:  Rifat [ Воскресенье, 06 Декабрь, 2020 15:10 ]
Заголовок сообщения:  Re: Что делать с LEN в амд64?

Как один из возможных вариантов:
- LEN возвращает INTEGER и ASSERT, если INTEGER превышен, хотя это может быть и излишне, так как переполнения в других местах не проверяются;
- LONGLEN возвращает LONGINT, по идее программист сам должен знать, где могут быть очень большие массивы, а где нет.

Автор:  Александр Ильин [ Воскресенье, 06 Декабрь, 2020 15:13 ]
Заголовок сообщения:  Re: Что делать с LEN в амд64?

Симетрично надо бы и NEW ограничить тогда.

Автор:  Илья Ермаков [ Воскресенье, 06 Декабрь, 2020 16:06 ]
Заголовок сообщения:  Re: Что делать с LEN в амд64?

Rifat писал(а):
Как один из возможных вариантов:
- LEN возвращает INTEGER и ASSERT, если INTEGER превышен, хотя это может быть и излишне, так как переполнения в других местах не проверяются;
- LONGLEN возвращает LONGINT, по идее программист сам должен знать, где могут быть очень большие массивы, а где нет.


Поддерживаю.
Или просто отрубить вариант огромных массивов (выше аргументировал).
Или делать вот так.

Автор:  SovietPony [ Воскресенье, 06 Декабрь, 2020 18:39 ]
Заголовок сообщения:  Re: Что делать с LEN в амд64?

Плюсую за ограничение длинной INTEGER. На жабе же живут как-то с int для тех же самых целей и никто не возмущается.

(а как сиё решено в других 64-битных оберонах?)

Автор:  adimetrius [ Понедельник, 07 Декабрь, 2020 13:17 ]
Заголовок сообщения:  Re: Что делать с LEN в амд64?

SovietPony писал(а):
(а как сиё решено в других 64-битных оберонах?)


В А2 так же не прямого ограничения на длину массива, а LEN возвращает тип SIZE :shock:, который привязан к платформе.

Автор:  adimetrius [ Понедельник, 07 Декабрь, 2020 13:30 ]
Заголовок сообщения:  Re: Что делать с LEN в амд64?

Илья Ермаков писал(а):
Но: при выходе в 64 бит и на современных объёмах ОЗУ возникают и новые возможности для мат. приложений.

Кого бы нам напрямую расспросить, кто занимается такими большими приложениями? (А то в моих приложениях если >10МБ, я уже беспокоюсь ;) )

Федор Васильевич, если вы читаете - как в ваших физических больших задачах: нужны ли сверхбольшие массивы?

Илья Ермаков писал(а):
Но на но: что-то практическое всё равно занимает от 8 байт, а практически-интересное - ещё и многомерное.


Ну, INTEGER в массиве по-прежнему может спокойно занимать 4 байта. Но про многомерность - мне кажется, весомый аргумент: если кому-то нужен доступ к такой большой памяти - можно организовать многомерность. Как в прикладных (мат-физ?), так и в системных задачах.

Автор:  Comdiv [ Понедельник, 07 Декабрь, 2020 16:53 ]
Заголовок сообщения:  Re: Что делать с LEN в амд64?

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

Автор:  Иван Денисов [ Понедельник, 07 Декабрь, 2020 16:56 ]
Заголовок сообщения:  Re: Что делать с LEN в амд64?

Говорят, что это нормально, что объекты не должны быть больше 2Gb.
https://docs.microsoft.com/en-us/dotnet ... dfrom=MSDN
"By default, when you run a 64-bit managed application on a 64-bit Windows operating system, you can create an object of no more than 2 gigabytes (GB)."

Автор:  Борис Рюмшин [ Вторник, 08 Декабрь, 2020 10:56 ]
Заголовок сообщения:  Re: Что делать с LEN в амд64?

Поддержу мысль, что для массивов достаточно INTEGER (32 бита). Понятно, что иногда хочется большими объёмами оперировать, но для этого можно специальные системные средства создать.

В любом случае, сейчас имеет смысл создавать 64-битную версию полностью совместимую с 32-битным КП. А потом уже думать над особенностями.

Автор:  Wlad [ Вторник, 08 Декабрь, 2020 20:57 ]
Заголовок сообщения:  Re: Что делать с LEN в амд64?

На потенциальный размер массива (как и на обозначение его размера в элементах) должно быть ограничение ТОЛЬКО в виде доступной памяти (физической, виртуальной, какой-то там ещё, до которой система позволяет-таки иметь доступ в рамках синтаксиса языка).

Автор:  Info21 [ Вторник, 08 Декабрь, 2020 21:02 ]
Заголовок сообщения:  Re: Что делать с LEN в амд64?

Язык не должен скрывать сложность под капотом.

Можно оставить совместимый ARRAY и просто иметь в виду на будущее какой-нибудь LONGARR.

Автор:  Oleg N. Cher [ Среда, 09 Декабрь, 2020 00:43 ]
Заголовок сообщения:  Re: Что делать с LEN в амд64?

Поддерживаю ограничение MAX(INTEGER) для максимальной длины встроенных массивов.

В Ofront+ есть подвижки для выбора типа длины массивов опционально: INTEGER или LONGINT. Но я решил не развивать эту опцию, а в будущем даже и убрать. Поясню. Для специфических математических задач с огромными объёмами данных в виде массивов > 2Gb размещать данные сверхбольшого массива в линейной области памяти слишком неэффективно - такого большого непрерывного куска памяти может даже и не оказаться. Ну и код будет полностью несовместим с 32-битными платформами. Забивать огромным массивом непрерывный кусок виртуальной памяти не так уж хорошо. С огромными массивами надо работать с учётом возможности их фрагментированного размещения, что будет намного гибче. Нужны другие (библиотечные) механизмы для сверхбольших массивов, в т.ч. совместимые с 32-битными ОС.

Автор:  Сергей Оборотов [ Четверг, 10 Декабрь, 2020 10:43 ]
Заголовок сообщения:  Re: Что делать с LEN в амд64?

Ограничение на длину массива было и в 16-разрядных системах, однако.

Автор:  kekc_leader [ Среда, 16 Декабрь, 2020 15:43 ]
Заголовок сообщения:  Re: Что делать с LEN в амд64?

Иван Денисов писал(а):

Ого, там ещё написано и вот что:
(Because Visual Studio is a 32-bit application, when it is installed on a 64-bit system, it runs under WOW64.)

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