Войти
ФлеймФорумПрограммирование

realloc_t

Страницы: 1 2 Следующая »
#0
21:41, 23 мая 2017

Всем привет.

Есть идея сделать realloc на системном уровне не из одной функции, а из двух.
Я только начал думать в этом направлении, поэтому пока уделаю внимание только сценарию использования realloc, где new_size>old_size.

В общем идея в том, чтобы сделать две функции вместо одной типа:

realloc_t realloc_begin(void*ptr,size_t size){...}
void      realloc_end(realloc_t){...}

где realloc_t что-то типа:

struct realloc_t{
  void*ptr; // already realloced
  size_t size;
};
очевидно API сыроват, возможно лучше сделать, чтобы realloc_begin возвращал void* как и старая версия, а realloc_end принимал её, а ещё чтобы последний можно было не вызывать вообще в случае если ... а ладно пока остановимся на том что написано выше, т.к так похоже проще объяснить идею.

Разбиение на два вызова нужно для того, чтобы поймать момент когда низкоуровневой системе в виртуальном адресном пространстве не получается выделить кусок памяти требуемого размера по старому указателю и он выделяется по новому и уже выделен, но система ещё не успела перенаправить/занулить/залочить/освободить страницы памяти по старому указателю. То есть перед вызовом realloc_end в этом случае прога будет находиться в состоянии когда есть два указателя на память и оба работают, но частично ссылаются на одну физическую память.

теперь если мы разрабатываем новый какой-то С++ подобный ЯП, то мы можем добавить в него новую фишку(realloc_ctor):

struct t_foo{
  foo(){...} // default_ctor
  foo(const foo&){...} // copy_ctor
  foo(foo&&){...} // move_ctor
  foo(foo&&,realloc_t){...} // realloc_ctor
};

набросок псевдокода реализации std::vector`а эксплуатирующий это:

template ...
struct vector{
  ...
  void resize(size_t n)
  {
    auto rec=realloc_begin(ptr,n*sizeof(value_type));
    if(rec.ptr!=ptr)realloc_elems_to(rec.ptr);
    realloc_end(rec);
    build_news_elems_up_to(n);
  }
};

норм?


#1
23:50, 23 мая 2017

Достаточно лишь одного

bool realloc_inplace(void* pointer, size_t new_size);
И можно будет крестоконтейнеры писать через него.

#2
0:37, 24 мая 2017

Adler
> сделать realloc на системном уровне не из одной функции, а из двух
на каком уровне?

Adler
> низкоуровневой системе в виртуальном адресном пространстве не получается
> выделить кусок памяти требуемого размера по старому указателю и он выделяется
> по новому и уже выделен, но система ещё не успела
> перенаправить/занулить/залочить/освободить страницы памяти по старому
> указателю.
Ты уверен что это все происходит на самом деле в юзер левел менеджере памяти?

#3
0:43, 24 мая 2017

1 frag / 2 deaths
что предлагаешь делать, когда в виртуальном адресном пространстве страница памяти с адресом pointer+page_size уже занята каким-то другим объектом/массивом?

#4
1:06, 24 мая 2017

exchg
> на каком уровне?
например, на уровне ядра OS.

exchg
> Ты уверен что это все происходит на самом деле в юзер левел менеджере памяти?
я не уверен, но думаю что на уровне ядра/hardware, но вроде это ничего не меняет.

#5
1:22, 24 мая 2017

Adler
> например, на уровне ядра OS.
тогда получается, что твой новый язык программирования залочен на одну ОС?

Adler
> я не уверен, но думаю что на уровне ядра/hardware, но вроде это ничего не
> меняет.
а зачем вообще лезть на этот уровень, если бытует подход, позволяющий прикрутить
к почти любому языку почти любой менеджер памяти (с любыми фантастическими апи)
который сам по себе весьма слабо связан с ядром/хардваром и прочим счастьем?

#6
1:56, 24 мая 2017

exchg
> тогда получается, что твой новый язык программирования залочен на одну ОС?
лочить необязательно, а вообще меня больше интересует насколько эта фича увеличивает жизнеспособность проги/языка/ОС.

exchg
> а зачем вообще лезть на этот уровень
не лезу, только идеи толкаю несмотря на существенный риск не достучаться до товарищей которые отвечают за эти уровни.

#7
11:02, 24 мая 2017

Adler
> что предлагаешь делать, когда в виртуальном адресном пространстве страница
> памяти с адресом pointer+page_size уже занята каким-то другим
> объектом/массивом?

Смотри, я жирным выделил:

bool realloc_inplace(void* pointer, size_t new_size);

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

#8
12:07, 24 мая 2017

1 frag / 2 deaths
> Программа узнаёт, что удлинить имеющийся кусок не вышло,
ок, давай я расскажу, что должно происходить в этом случае если низкоуровневая система поддерживает realloc_begin/realoc_end. см.ниже.

1 frag / 2 deaths
> дальше применяет стандартный алгоритм с выделением нового куска
а realloc_begin выделяет новый кусок виртуальной памяти размером new_size, по адресу new_ptr, а потом сам изменяет дескрипторы виртуальных страницы памяти от new_ptr до new_ptr+old_size так, чтобы они ссылались на тот же кусок физической памяти на который ссылается old_ptr, то есть избегает копирования физической памяти.

под оставшиеся примерно (new_size-old_size)/page_size страниц виртуальной памяти надо выделять реальную физическую память.

1 frag / 2 deaths
> вызовом стд::мове
при использовании realloc_begin нельзя вызывать обычный move_ctor для таких виртуальных адресов которые в низкоуровневой системе ссылаются на один и тот же кусок физической памяти.

1 frag / 2 deaths
> удалением старого куска
при использовании realloc_begin, realloc_end - просто отвязывает дескрипторы виртуальных страницы старого виртуального куска памяти.

1 frag / 2 deaths
> И в твоём случае то же самое будет.
всё ещё так считаешь?

#9
12:17, 24 мая 2017

Adler
> всё ещё так считаешь?
Ок, я понял твою идею.
Проще запретить в языке нетривиально реаллоцируемые объекты (хоть раз такие применял?), и тупо допилить на уровни оси обычный реаллок.

#10
12:54, 24 мая 2017

1 frag / 2 deaths
> Проще запретить в языке нетривиально реаллоцируемые объекты
Приведет ли это к необратимому увеличению жизнеспособности языка/прог/пользователей?

1 frag / 2 deaths
> нетривиально реаллоцируемые объекты (хоть раз такие применял?)
У меня есть свои умные следящие указатели, которые внутри используют двусвязные списки для реализации механизма похожего на subscribe/publisher, который используются внутри move_ctor, а так же при связывании/уничтожении владельца. Я на этих штуках сделал свою реализацию RTTI(там описатели типов ссылаются друг на друга умными следящими указателями) + супер крутую автоматическую систему сериализации/десериализации почти любых структур(как использующих так и не использующих умные следящие указатели).

#11
13:00, 24 мая 2017

Adler
> У меня есть свои умные следящие указатели, которые внутри используют двусвязные
> списки
И тебе нужно реаллоцировать именно вектор из таких указателей?

#12
13:53, 24 мая 2017

1 frag / 2 deaths
> И тебе нужно реаллоцировать именно вектор из таких указателей?
раньше обычно делал так: в std::vector запихиваем структуры, а в структуры запихиваем умные следящие указатели, что в общем эквивалентно std::vector<TWeakPtr<T>> если в структуре ничего кроме умного указателя нет, да в прочем даже если есть - это почти ничего не меняет.
ну например:

struct t_cmd{
  TSelfPrt<t_cmd> self;
  TWeakPtr<t_cmd> next;
  std::string type;
  bool deaded;
  vec2d pos;
  vec2d v;
  real r;
};
struct t_phys_prog_instance{
  std::vector<t_cmd> arr;
  TWeakPtr<t_cmd> cur;
  bool deaded;
  vec2d pos;
  vec2d v;
  real r;
  ...
};
struct t_world{
  vector<t_phys_prog_instance> entities;
  ...
};
потом я конечно деградировал ещё сильнее, но не тема об этом.
#13
14:13, 24 мая 2017

Adler
> а realloc_begin выделяет новый кусок виртуальной памяти размером new_size, по
> адресу new_ptr, а потом сам изменяет дескрипторы виртуальных страницы памяти от
> new_ptr до new_ptr+old_size так, чтобы они ссылались на тот же кусок физической
> памяти на который ссылается old_ptr, то есть избегает копирования физической
> памяти.
Что? Опять магия? Не взлетит.

#14
15:11, 24 мая 2017

Adler
Ну тогда ещё вариант, на х64 должен работать: выделяешь маллоком террабайт оперативы, для векторов отдельный пул, тупо выдаёшь им адреса с разницей в гигабайт, то есть чтобы в виртуальном адресном пространстве коллизий не должно быть. А дальше кажись система сама догадается, что ты не используешь всю запрошенную память, и сама реально будет выделять тебе лишь сколько надо.

Страницы: 1 2 Следующая »
ФлеймФорумПрограммирование

Тема в архиве.