LINUX.ORG.RU

А почему умерли разные типы указателей?

 ,


0

2

Привет, ЛОР!

Тащемта, вопрос. В x86-16 были near и far pointers, что позволяло экономить на размере указателя в ту глубокую древность. Почему этот концепт не попал в 64-битные архитектуры? Ведь с учётом локальности, делать все указатели 64-битными выходит в конский расход памяти при том, что большая часть бит указателей в рамках одного экземпляра структуры данных (допустим, связанный список или дерево) будут одинаковыми. А значит, можно сэкономить кучу памяти, сохраняя только последние N бит указателя и хранить полный указатель, например, только в заголовке структуры данных.

В общем, вариантов как это может облегчить жизнь просто вагон. Почему этого сейчас нет нигде?

Update:

Вообще, такой подход дохрена где применяется. Гуглить «succinct data structures». Например, вот это: https://web.archive.org/web/20160312010342/https://www.computer.org/csdl/proceedings/focs/1989/1982/00/063533.pdf

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

★★★★★

Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от Stanson

Это ты пишешь обращение к памяти. А хранится в памяти то все равно будет qword если ты написал struct { void *ptr }.

Если структур очень много, то использование коротких указателей оправданно, или коротких индексов.

MOPKOBKA ★★★★★
()
Последнее исправление: MOPKOBKA (всего исправлений: 3)
Ответ на: комментарий от MOPKOBKA

Это ты пишешь обращение к памяти. А хранится в памяти то все равно будет qword если ты написал struct { void *ptr }.

Да, но использоваться для адресации будет не полный адрес, а регистр хранящий базовый адрес + смещение которое будет занимать уже не qword а например byte.

Stanson ★★★★★
()

А если по теме топика, то там где надо, оно так и происходит: есть арена, на которую ссылается базовый указатель, а все объекты внутри неё ссылаются друг на другу по относительным адресам.

gaylord
()
Ответ на: комментарий от static_lab

Сорян, миллион записей в том бенче был.

$ wc -l file.json                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
1000002 file.json
$ du -sh file.json                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
14M     file.json
$ head file.json                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
{
  "quXEi": "dkXfc",
  "Sbnov": "Eqrzh",
  "LxX9D": "rxvBr",
  "F3IhM": "hbkdv",
  "1tJda": "DUSnH",
  "d6TD6": "XXFT2",
  "mwmTh": "snXqY",
  "Eq2Ec": "0CB01",
  "GpJ18": "asTSW",

Потребление по памяти как я и выше писал, там всё верно.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от Anoxemian

Понимаешь, в чем проблема… обычно когда речь идет о Python, важна специфика. Python это такой общий язык, на котором пишут QA, ML, AI, трейдинг, сервисы и черта в ступе. И в среднем за все это тоже платят больше, чем за C.

gaylord
()

не умерли, вычёааа :)
https://en.wikipedia.org/wiki/JMP_(x86_instruction)#Types_of_Jumps
short jump навалом :) в генерируемом «аппаратном» коде переходов где необходимо перепрыгнуть всего лишь на +127 / -127 байт относительно текущего указателя программы огромное количество. зачем туда впихивать что-то другое «более длинное» ?? :)

pfg ★★★★★
()
Ответ на: комментарий от hateyoufeel

Прямо чёткого плана тестов у меня конечно же нет.

Но начинал бы я с бенчмарков браузеров, например, https://browserbench.org. Это если на X32 ABI будут работоспособные Firefox и Chromium. Для «нативных» приложений я бы начал с Phoronix Test Suite. В PTS вроде много что есть, но я бы в первую очередь смотрел на что-то упирающееся в CPU и кеш, например подсчёт числа π. Потом что-нибудь, что использует побольше памяти, например CFD. Потом что-нибудь, что работает с сетью, вроде бенчмарка веб-сервера. И ради интереса сборка компилятором чего-то на скорость. Компиляция — не честный бенчмарк, потому что там обычно не кросс-компиляция под общую цель, а сборка под текущую платформу. Но просто поглазеть может быть интересным.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

например подсчёт числа π

Если для вычислений будет использоваться длинная арифметика, то вообще никакой выгоды не будет. Лучшим выигрышем будет там где куча указателей типа бинарных деревьев или структур с кучей указателей.

V1KT0P ★★
()

x86-16 были near и far pointers

Тред не читал.
Там в эльбрусах есть некая система защиты, когда в указателях только половина указателя используется для адресации, а вторая половина - для безопасности. Во второй половине указываются границы памяти, по которым разрешено обращаться с помощью этого указателя и таким образом обеспечивается усиление безопасности. Или это другое?

u5er ★★
()
Ответ на: комментарий от hateyoufeel

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

Не совсем понятно про какие указатели и какой расход памяти идет речь.
Операционная система тебе выделяет память в юзерленде и выдает указатель на начало, предполагая что конец ты сам знаешь посчитаешь. Либо ты сам берешь и получаешь указатель на стек.
Какой может быть близкий и далекий указатель если у тебя кусок памяти заняла операционная система, а дальше N приложений, их модулей и данных?

uin ★★★
()
Последнее исправление: uin (всего исправлений: 1)

что позволяло экономить на размере указателя в ту глубокую древность

Они там были не поэтому, а для совместимости с ещё более древними камнями.

Почему этот концепт не попал в 64-битные архитектуры?

Потому что не нужно поддерживать совместимость, очевидно же.

конский расход памяти

Расход памяти на указатели сейчас меньше чем тогда, если считать относительно объёма программы и данных. Т.е. экономия на указателях – это экономия на спичках.

no-such-file ★★★★★
()
Ответ на: комментарий от hateyoufeel

Какие ещё детали реализации, это сама суть, это то, что ты и обсуждаешь тут. Именно то что под капотом, а не то что в виде «API» последнее ты и так используешь, ведь 64битных указателей настоящих почти и нет, они там в реальности 40 с чем-то, правда памяти от этого больше не становится ибо >32. Так что для тебя должно быть важным что реальные указатели, реальные данные что под капотом что вне его <=32 бит (для 64битных машин) и <=16 (для 32битных и так далее), а не 33 бита под капотом и 32 в «API» (заметь что API в кавычках, но суть должен понять).

Жизнеспособность подхода и определяется тем что творится под капотом.

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

Почему не используется?

  • Гарантированное усложняет всё
  • Гарантированно замедляет всё
  • Выигрыш экономии памяти мизерный
    • Так как обычно в памяти много данных, а не много указателей

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

Прикольно, но не выгодно.

anonymous
()
Ответ на: комментарий от anonymous

64битных указателей настоящих почти и нет, они там в реальности 40 с чем-то

Тебя обманули, анон. Они 64-битные, занимают ровно 64 бита (8 байт) памяти. Canonical form address – это про другое.

Дальше твой щитпост я не читал.

hateyoufeel ★★★★★
() автор топика
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от luke

есть стата по указателям

Есть здравый смысл. Объёмы данных выросли в миллионы раз. Использование указателей точно не выросло в миллионы раз (осталось примерно прежним). Хотя бы потому что в условно «плохом» случае, когда на каждый int используется указатель, использование остаётся 1:1 к данным, но в большинстве случаев данных на указатель значительно больше.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 2)

Когда были 32-битные дистры centos то простенький LNMP-сервер спокойно работал на vps с 512М памяти. Когда пришлось таки переехать на 64битную centos, то уже 512 не хватало, надо было 1Г заказывать под то же самое.

Однако тут многие с умным видом доказывают, что экономии памяти не выйдет. Мда

Psilocybe ★★★★
()
Ответ на: комментарий от Psilocybe

Когда пришлось таки переехать на 64битную centos, то уже 512 не хватало, надо было 1Г заказывать под то же самое

Потому что int вырос в 2 раза, а не потому что указатели стали больше.

no-such-file ★★★★★
()
Ответ на: комментарий от Psilocybe

Как-то мимо меня прошло…

Чтобы поддержать короткие указатели в 64-битной ОС не нужно ведь было линукс сильно перепиливать? Достаточно научить его выдавать память из короткого пула + научить компиляторы этим коротким указателям. И, собсно, всё!

Или оно так и работало?

ahdenchik
()
Ответ на: комментарий от ahdenchik

Все пишут что-то типа int32_t и так далее

Ага, под ifdef-ом, типа

#if (NGX_PTR_SIZE == 4)
#define NGX_INT_T_LEN   NGX_INT32_LEN
#define NGX_MAX_INT_T_VALUE  2147483647

#else
#define NGX_INT_T_LEN   NGX_INT64_LEN
#define NGX_MAX_INT_T_VALUE  9223372036854775807
#endif

Т.е. те же яйца вид сбоку. Просто более предсказуемо.

no-such-file ★★★★★
()
Ответ на: комментарий от anonymous

Ещё один клоун одноклеточный… Речь про то, что на 64 битной машине используются 64 битные целые. Я про Си конкретно ничего не говорил, нахер ты сюда это припёр?

no-such-file ★★★★★
()