Си не умеет хранить тип значения. Для него это просто байты в памяти, которые можно так, а можно эдак. Об этом уже миллион раз говорено, но я снова и снова буду это вспоминать
( Read more... )
вот ты пишешь - буду пользовать не указатель, а два указателя - не 32 бит а 64.
нельзя ли сэкономить на длине того из них, который на тип данных? договориться сам с собой, что описание типа данных не может находиться в любом из 2^32 адресов, а только лишь в любом из 2^20 адресов, начинающихся с 0x.... чего-то там.
ну то есть, хранить все описания типов в выделенной области памяти, и знать её начало (смещение). и допустим старшие 8-12-16 бит указателя на тип - использовать под флаги-таги. а для того, чтобы получить указатель на тип данных - использовать младшие биты, а старшие брать из постоянного адреса "начало области описания типов"
можно пойти дальше, и отвести часть флагов-тагов на выбор области, в которой описания хранить (её смещения). но будет тормозить. но можно будет в нескольких кусках адресного пространства хранить типы.
хмм.. вроде как страницы/сегменты в msdos, похожая механика
можно даже картировать типы - сделать лукап. еще и быстрее поди получится, чем манипуляции с битами.
область памяти для типов может потребоваться большая - но самих-то типов количество счётное и не очень большое. соответственно, из 32 бит указателя на тип памяти вообще будут использоваться ченибудь 10 (сомневаюсь, что средняя прога вылезает за 1000 типов данных)
сейчас 32-битные влезают в указатель, который тоже 32-битный. Там, где тип прописан как "UINT32", программа понимает, что надо брать не значение по указателю, а сам указатель. Если я сделаю поля ячеек более узкими, то 32-битное целое будет занимать не один указатель (который теперь будет и не указатель вовсе, а просто индекс), а, например, сразу всю ячейку. Не катастрофа, но для хранения 32-битных чисел потребуется заводить ДВЕ 16-битных ячейки - в одной лежит тип и индекс, во второй, занимая оба 16-битных CAR и CDR, само число. Ещё менее удобно, если ширина ячеек ещё меньше. И в этом случае получается замена шила на мыло - хотели уйти от 2*32 бита, пришли к 2*16 + 32 бита... :)
С другой стороны, чисто 32-битными числами оперировать надо не так уж часто - они удобны, но на них свет клином не сошёлся. Можно сделать два разных типа, 16-битное целое (которое будет работать по старой схеме) и 32-битное (или 64, или вообще bignum!), которое будет работать по новой схеме, или вовсе по какой-то ещё непридуманной.
Да, можно. Просто с указателями проще всего. А так-то да, вместо них можно хранить номера меньшей разрядности - и как "указатели" на ячейки, и как "указатели" на, к примеру, какие-то элементарные встроенные функции. Я об этом думал, но пока мне кажется, что хранение реальных указателей немного проще в реализации.
С другой стороны, если хранить номера или индексы, проверка выхода за диапазон становится совсем уж тривиальной.
Так не сильнее же "тормозить", в смысле дополнительных затрат на дополнительные проверки и разворачивания. То есть, если сейчас что-то вроде newatom = oldatom->type->create(data) то будет newatom = types[oldatom->type]->create(data) не сильно сложнее.
Короче, у меня есть идея проверить и такой вариант. В самом деле, должно быть компактнее.
Мало того, оно ещё и "переносимее" получится - индексы и т.п. можно абсолютизировать, в отличие от адресов. И тогда байт-код (который ещё не существует, но однажды ж появится) будет просто записью этих самых индексов (для опкодов, например), смещений (для адресов) и т.п.
нельзя ли сэкономить на длине того из них, который на тип данных?
договориться сам с собой, что описание типа данных не может находиться в любом из 2^32 адресов, а только лишь в любом из 2^20 адресов, начинающихся с 0x.... чего-то там.
ну то есть, хранить все описания типов в выделенной области памяти, и знать её начало (смещение). и допустим старшие 8-12-16 бит указателя на тип - использовать под флаги-таги. а для того, чтобы получить указатель на тип данных - использовать младшие биты, а старшие брать из постоянного адреса "начало области описания типов"
можно пойти дальше, и отвести часть флагов-тагов на выбор области, в которой описания хранить (её смещения). но будет тормозить. но можно будет в нескольких кусках адресного пространства хранить типы.
хмм.. вроде как страницы/сегменты в msdos, похожая механика
Reply
область памяти для типов может потребоваться большая - но самих-то типов количество счётное и не очень большое. соответственно, из 32 бит указателя на тип памяти вообще будут использоваться ченибудь 10 (сомневаюсь, что средняя прога вылезает за 1000 типов данных)
Reply
Reply
я так п, твой каод различает, что перед ним - "указатель на тип" или что либо еще?
Reply
С другой стороны, чисто 32-битными числами оперировать надо не так уж часто - они удобны, но на них свет клином не сошёлся. Можно сделать два разных типа, 16-битное целое (которое будет работать по старой схеме) и 32-битное (или 64, или вообще bignum!), которое будет работать по новой схеме, или вовсе по какой-то ещё непридуманной.
Reply
но выравнивание тогда потеряется
но освободившиеся 6 байт можно потратить на что-то полезное
Reply
С другой стороны, если хранить номера или индексы, проверка выхода за диапазон становится совсем уж тривиальной.
Reply
newatom = oldatom->type->create(data)
то будет
newatom = types[oldatom->type]->create(data)
не сильно сложнее.
Короче, у меня есть идея проверить и такой вариант. В самом деле, должно быть компактнее.
Мало того, оно ещё и "переносимее" получится - индексы и т.п. можно абсолютизировать, в отличие от адресов. И тогда байт-код (который ещё не существует, но однажды ж появится) будет просто записью этих самых индексов (для опкодов, например), смещений (для адресов) и т.п.
Reply
Leave a comment