LINUX.ORG.RU

структура из массивов с минимумом накладных расходов

 , ,


1

1

Издалека начну. Есть некий хитрый контейнер, который обходится итератором. Элементы контейнера - структура определенная юзером. В структуре может быть несколько полей (в идеале разных POD-типов, но можно ограничиться пока одним).

Теперь самое сложное - в разных элементах некоторых полей может вообще не быть, может быть просто поле типа T, а может быть небольшой массив (одномерный или двумерный), и это будет меняться в runtime. При этом накладные расходы на хранение всего этого безобразия должны быть минимальны, то есть решение вида

struct E{
  std::vector<T> a;
  std::vector<T> b;
  std::vector<T> c;
  ...
};

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

Нужно:

  1. Понять как это вообще можно сделать.

  2. Хороший интерфейс для доступа ко всему этому.

  3. Хороший интерфейс для задания структуры пользователем.

  4. Желательно, но не необязательно - прикрутить к этому какую то интроспекцию, то есть что бы хранились типы полей и имена полей (как массив строк и sizeof-ов).


Пока что придумалось такое - в структуре заводится

std::vector<char> data; // тут лежат все данные
uint8_t sz[N][2];       // размеры полей как массивов
uint16_t off[N];        // смещения различных полей в data

где Т - число полей (в итоге расход 4 байта на поле - с этим как то можно жить) и для каждого поля name делаются функции

T& name(int i=0, j=0);
void resize_name(int szi, int szj, T defval=T());

и то и то делается макросами, то есть для юзера задание структуры выглядит как

struct E{
CELL_TABLE(10); // задаем N
ADD_FIELD(0, double, a); // номер поля, тип, имя
ADD_FIELD(1, float, b);
...
};

а доступ выглядит как

I->a() ... I->b(1) ... I->c(0,2) ...

если индекс вышел за пределы массива генерируется ошибка.

Вопросы:

  1. какие тут подводные камни, что можно улучшить?

  2. как это вообще называется (лучше назвать)?

  3. как к этому малой кровью прикрутить интроспекцию? То есть я хочу иметь возможность в runtime снаружи узнать все типы полей, имена полей, размеры типов полей.

cast @KennyMinigun , @hobbit;-)

★★★★

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

Ответ на: комментарий от Iron_Bug

За рекомендацию АСЕ спасибо, но есть нюанс - у нас скорость доступа всегда важнее чем скорость перестройки структуры данных. На скорость влияет вмного факторов, в частности взаимное расположение данных, поэтому когда нас перестает устраивать stl мы просто делаем это руками.

В АСЕ есть поддержка Z-кривой Мортона?

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

насчёт кривой - не знаю. он развивается, а я за ним не слежу в последние годы, ибо пишу в основном на С. но думаю, что вряд ли. потому что узкая специфика.

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

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

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

Спасибо:-) А овердохрена это сколько?

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

Ну вот, а у нас своя узкая специфика, и она не сетевая… Хотя для AMR м.б. он и будет полезен, но пока что у меня там свой менеджер.

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

ну, весь поток ОПСОСа, например. GSM+всякий там LTE. я не помню, сколько там гигабайт в секунду, но дохрена. также делали обработку данных качества печати на Гознаке. там было 10 гигов в секунду, но там мы на FPGA'шках часть данных обрабатывали, софт бы не справился, потому что там кроме всего ещё и риалтайм был - управление железом на огромной скорости.

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

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

По своей практике могу сказать, что ТС прав - преждевременная оптимизация зло. Сначала нужно выписать алгоритмы, их проверить на реальных данных, а потом уже смотреть где затыки в реализации. После чего опять смотреть на алгоритмы. В общем есть у оптимизации начало, нет у оптимизации конца :)

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

Да, масштабно.

У нас сеть обычно скрыта MPI, объем данных это память кластера. На фрагментацию раз напарывались (на старой либс кончалась память), пришлось заранее считать размеры выделяемых блоков.

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

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

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

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

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

Я использую питон.

А шо такое калькулятор с интерфейсом?! Мышкой тыкать? Так у меня нет мышки…

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

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

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

у меня тоже нет мыши. но тачпад есть. и клавиатура есть. у нормальных приложух есть хоткеи.

пистона у меня нет. я его планомерно уничтожаю, как вредный для ПО элемент.

Iron_Bug ★★★★★
()
Последнее исправление: Iron_Bug (всего исправлений: 1)
25 апреля 2020 г.
Ответ на: комментарий от Iron_Bug

Да, ACE как раз на такие задачи, но что значит весь поток, запихиваете небось на распределенной архитектуре сигнальный поток и раскидываете его по разным лезвиям и понеслось (АСЕ как показывает опыт самая вменяемая часть в таких проектах). Это Мера, небось, все?

pustota1
()

какие тут подводные камни, что можно улучшить?

1. Выравнивание может внезапно выстрелить на sse-инструкциях.

2. Работа с uint16_t в 64-битном режиме тормознутая

если индекс вышел за пределы массива генерируется ошибка.

Для этого необязательно хранить размеры индивидуальных массивов достаточно сделать +1 элемент в offsets и при доступе проверять, что (T*)&data[off[n]] + index < (T*)&data[off[n+1]]

Ну раз «возможно двумерные», тогда да, придется где-то хранить одну размерность.

как к этому малой кровью прикрутить интроспекцию

Вместо бесполезного sz сделать массив с кодами типов. Для этого нужно перейти от объявления полей к заданию списка полей. Кажется, что сделать это можно как макросами, так и шаблонами. Самый простой и очевидный способ

#define OFF(x) ((x) & 0x00FFFFFFu)
#define ROW_LEN(x) ((x) >> 24)
#define BASE_PTR(type, n) ((type*)(&data[offsets[n]])
#define COUNT(type, name) +1
#define NAME2ID(type, name) f_ ##name,
#define ACCESSOR(type, name) \
    // one-dimensional accessor \
    type& name(size_t index) { \
        constexpr size_t n = f_##name; \
        if (ROW_LEN(offsets[n]) != 0) throw runtime_error(#name " is a two-dimensional array!"); \
        if (BASE_PTR(type, n) + index >= BASE_PTR(type, n + 1)) throw runtime_error(#name "'s index out of range"); \
        return BASE_PTR(n)[index]; \
        } \
    // two-dimensional accessor \
    type& name(size_t row, size_t col) { size_t index = f_##name; ... }

struct array_info {
  const char *name;
  const char *type;
  size_t nrows;
  size_t ncols;
};

struct E {
#define FIELDS(XX) XX(double, a) XX(float, b) XX(int, c)
enum { FIELDS(NAME2ID) }; // f_a = 0, f_b = 1, f_c = 2
static constexpr size_t N = 0 FIELDS(COUNT);
uint32_t offsets[N + 1]; // оффсеты полей, пусть в старшем байте хранится длина строки для многомерного массива
FIELDS(ACCESSORS); // сгенерировались функции для доступа
void introspect(vector<array_info> &info) {
  info.resize(N + 1);
  size_t i = 0;
#define XX(type, name) \
  info[i].name = #name; \
  info[i].type = #type; \
  info[i].ncols = ROW_LEN(offsets[i]); \
  info[i].nrows = (OFF(offsets[i + 1]) - OFF(offsets[i])) / sizeof(type) / ROW_LEN(offsets[i]); \
  i++;
  FIELDS(XX);
#undef XX
}
#undef FIELDS
};

И по итогу оказывается, что номер field-а тебе вообще был не нужен.

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

ничего подобного даже близко. на Гознаке делали всё с оборудованием, там гораздо сложнее система. компы там не справятся с потоком. там свои платы. и там никаких сторонних библиотек не было. ACE использовался в телекоме (там скорости в разы меньше), и очень поверхностно, не как основная часть, конечно. и вовсе не для сигналов. там я на ассемблере куски писала, чтобы быстрее было.

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

Чего то не фига не понятно, если «не для сигналов» имеется ввиду не для сигнального/управляющего трэфика, то это может быть только пользовательские данные, соответсвенно, если «весь поток» ОПСОСа это десятки гигабит (как минимум) в секунду, непонятно ни зачем это делать (СОРМ++ так не работает, хотя, почитав детаи о «пакете Яровой» – может и работает уже), даже и распределенным способом,ни какие же потоки на Гознаке

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

Я тут, кстати, посмотрел Ваше сообщение по поводу карточек на 1 ТБайт и поток в 1Гбайт, как нечто серьезное в смысле данных и достижений, ну как то плохо это все стыкуется. Я прикидывал что может быть на Гознаке так: 50 параметров (какие конкретно не разу не интересно, какие у них печатающие машины и так отлично известно – Koenig & Bauer, как почти и у всех остальных) в 10 байт это 4000 бит и миллион в секунду это 4Гбит, ну еще какой нибудь оверхед раза в 2, как раз 1 Гбайт, не вижу тут bleeding edge никакого – line rate на 10Гбит разьемах давно уже COTS, с другой стороны Вы рассказываете, что снимали весь поток ОПСОСа на LTE, a это 10ки гигабит, конечно.

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

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

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

Да довольно понятно, что Вы не будете делится деталями «реализации», хотя тут до реализации, не говоря уж о деталях, как до Пекина на карачках, но в каждом посте, будете гордиться автоматизацией Гознака — нет и не надо, не велика потеря. А по поводу фашизм или не фашизм пакет Яровой — разговор сейчас не об этом, а о десятках гигабит потока без пользовательских данных — крайне маловероятно, это я говорю как человек, работавший на фирму, которая делала и делает Ваши любимые «осциллы» от 50К$ и где были всякие другие отделы и который видел технические требования 2 из 3 федеральных ОПСОСов, примерно так же и с сотнями гигабит на Гознаке —оценка основывается на моей работе на крупного производителя оборудования для производства бумаги, помимо всего прочего, но область закрытая, работал я там довольно давно, так что будем толковать сомнения в Вашу пользу — маловероятно. Всего хорошего!

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

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

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

федеральные российские ОПСОСы вполне себе закупали оборудование у той самой фирмы (другие отделы, не осцилльные, разумеется). Будет для Вас шокирующим, но у той фирмы, которая, якобы только в «осциллы» умеет был и свой (прикупленный) отдел, который с DDoS боролся. Сюрприз, правда? И да – Гознак не производитель бумаги – я бы никогда не догадался, он ее потребитель, поэтому сомнения в Вашу пользу, но откуда там сотни гигабит берутся, которые якобы только от «деталей реализации» становятся понятными – это пусть Вам останется на память, вместе с рассказиками про автоматизацию Гознака.

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

Тише девочки, не ругайтесь;-)

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

вы придумали какую-то фирму и теперь что-то мне про неё впариваете. но те компании, у которых мы закупали осциллы a) не российские и не имеют никаких филиалов в РФ b) не занимаются никакими ддосами и вообще сетями, а также не вяжут веники и прочее, и прочее. c) гознак сам делает бумагу для своих нужд. он не закупал никакое оборудование для её производства в РФ.

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

Вам так безразличен мой опыт собирания огурцов на плантациях, что Вы строчите комментарии тут, только в путь, ну-ну. а) филиалов нет, а channel partners есть и что? b) вранье. смотрите историю фирмы Arbor — так понятно? с) и что из этих, довольно корректных в своем содержании утверждений, следует в контексте возможности оценить величину потока данных на основе опыта работы на поставщика оборудования для производства бумаги?

Так что отстаньте уже от меня, пусть Ваши «детали реализации», гордость за автоматизацию Гознака с сотнями гигабит на линию в секунду и десятки гигабит сигнального трэфика останутся лично с Вами.

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

я ничего не говорила про осциллы (кстати, их покупали в Штатах). вы придумали какую-то свою версию про осциллы, которые якобы вы делали (американцы прямо спят и видят, как вы им осцилл делаете) и параллельно зачему-то продавали что-то каким-то «опсосам», только непонятно что и где, и при чём тут ddos'ы. американцы с опытом более 50 лет изготовления инструментов для измерений точно не занимаются разработкой софта от ддоса. тем более для опсосов из Эрефии. а потом вы вдруг обобщили ваш опыт продажи офисной бумаги на Гознак и сделали из этого какие-то далеко идущие выводы о скоростях технической информации на фабрике печати. и мне вот это всё сейчас втираете. мне это неинтересно и я считаю это чем-то нездоровым.

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

Отстаньте от меня, наконец,припадочная, Вам было ясно написано, что «… и где были всякие другие отделы…»—- идите уже и по слогам прочитайте что Вам пишут и про «осциллы» Вы конечно тоже писали, откуда я бы еще знал это слово, могу и ссылку привести, где.Кстати, и вторая фирма ( в девичестве HP), которая делала «осциллы» с приведенными параметрами вполне себе имела решение для ОПСОСов —- acceSS7 назваается, погуглить Вам или сами сможете?

pustota1
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.