?
 

ucl internals

About Уничтожить всех уродов

Previous Entry ucl internals 5 июл, 2016 @ 06:43 Next Entry
Понял, что мне очень сильно не нравится пухлое представление самых частоупотребимых сущностей: коротких чисел и символов.

Я не проводил никаких исследований на эту тему, но что-то мне подсказывает, что весьма существенная часть реальных переменных, используемых в эмбеде - 16-битные. Размеры буферов, индексы внутри них, разрешение дисплеев, скорости перемещения и т.п., и т.д. - всё это чаще представимо в виде небольших чисел, высокая разрядность тут ни к чему, да и дорого. Кроме этого, существенная часть всяких рабочих переменных записывается в виде одно-, двух- и трёхбуквенных мнемоник, типа x, v1, lst и так далее. То есть имеет смысл подумать над максимально компактным представлением некоторых данных (сохранив, разумеется, возможность представления более крупных данных в неприкосновенности: 32- и 64-битные числа, равно как и ДлинныеИПонятныеИменаПеременных тоже имеют право быть!).

Хак относится к little-endian машинам минимум 32-битной разрядности. Для адаптации его к big-endian нужно поменять порядок полей в структурах.


Все данные и указатели оборачиваются в специальные структуры с тэгами, позволяющими определить вид содержимого.

N

31

30

29

28..24

23..16

15..8

7..0

CAR mnemonic

gc

cons

category

opt

data

data

data

When 0

working

Atomic

container

Atomic options

Misc.data

When 1

garbage

Cons cell

pointer

pointer>>3

CDR

t.b.d.


В том случае, если данные можно полностью уместить внутрь поля data одного такого регистра, представление данных получается таким:

N

31

30

29

28..24

23..0

|← 8 bits →|

CAR mnemonic

gc

cons

category

opt

data

0

0

0

options

Atomic container data

CDR

Not available; has no meaning; don't try to use it


В том случае, если данные можно полностью уместить внутрь ячейки (которая, по традиции, представляет собой пару указателей, но на самом деле не обязательно является парой именно УКАЗАТЕЛЕЙ (просто таков её размер)), представление данных получается немного иным. В поле CAR лежит некое краткое описание типа данных и, опционально, кусочек этих данных (возможно, какие-то служебные сведения), а в поле CDR лежит либо указатель (например, на C-style строку), либо какая-то иная нужная нам порция данных (например, 32-битное число):

N

31

30

29

28..24

23..16

15..0

CAR mnemonic

gc

cons

category

opt

flags

data

0

0

1

options

Atomic flags

Additional atomic data

CDR

Atom's data (also can be pointer with any align)


CONS-ячейка, с учётом этих оптимизаций, выглядит так:

N

31

30

29

28..24

23..16

15..8

7..0

CAR mnemonic

gc

cons

category

opt

data

0

1

0: container

options

Atomic container data

1: pointer

Pointer to CAR; shifted >> 3 (align 8)

CDR mnemonic

-

-

size

opt

data

0: container

options

Atomic container data

1: pointer

Pointer to CDR; shifted >> 3 (align 8)


Низкоуровневый код выглядит несколько странно, но однако же, простенький тяп-ляп тест даёт такой результат:
atomic cell; generic form; [retrieve-long-data, length 18]
atomic cell; short form; [symbol]
atomic container [a4]


В квадратных скобках - гипотетические имена символов. В первом случае имя не помещается ни в указатель, ни даже в ячейку, и хранится в куче как обычная C-строка (в атом же занесён указатель на эту строку). Во втором случае имя не помещается в указатель, но влезает в ячейку, в третьем случае имя полностью уместилось внутрь указателя. Для коротких имён экономия памяти получается весьма существенной, с лихвой окупающая пару дополнительных проверок нескольких битов.


Правильная организация структур данных - залог успеха.
Оставить комментарий
[User Picture Icon]
From:mbr
Date:Июль, 5, 2016 06:25 (UTC)
(Link)
> высокая разрядность тут ни к чему, да и дорого.

Это как раз относится к 16 битному представлению 32 разрядных процессоров. Если не ужимать в памяти, 16 битные переменные все равно будут занимать 32 бита, если ужимать - unaligned access, адовый байтсекс, промахи кэша и прочие радости. Про код я вообще молчу.
[User Picture Icon]
From:kincajou
Date:Июль, 5, 2016 07:02 (UTC)
(Link)
дык, в моей реализации минимальная granularity как раз равна ширине машинного слова, для 32-битных процессоров будет 32 бита. А что напихать внутрь этих битов - это уже моя забота.
[User Picture Icon]
From:mbr
Date:Июль, 5, 2016 08:00 (UTC)
(Link)
Костыли и велосипеды.
[User Picture Icon]
From:kincajou
Date:Июль, 5, 2016 08:08 (UTC)
(Link)
Отчасти это эмуляция тэговой архитектуры, отчасти оптимизация по расходу памяти - без неё на хранение коротких чисел будет уходить два машинных слова, а с ней - одно. А если это число лежит в списке, то без оптимизации будет уходить аж четыре слова (ячейка списка с указателем на следующую ячейку и на "двухсловное" значение), а с ней - только два слова (ячейка с указателем на следующую и САМО ЗНАЧЕНИЕ, а не указатель на него). Двухкратная экономия памяти для частовстречающихся случаев - это, имхо, несомненное благо, ради которого можно немного подумать.

Любая оптимизация это костыли.
[User Picture Icon]
From:kincajou
Date:Июль, 5, 2016 08:10 (UTC)
(Link)
прелесть в том, что все эти костыли с велосипедами будут абсолютно не видны снаружи. С т.з. пользователя работать будет одинаково, что список 64-битных чисел, что 8-битных. Список и список. А расход памяти будет меняться ОЧЕНЬ значительно в пользу более коротких величин
(Оставить комментарий)
Top of Page Разработано LiveJournal.com