Jump to content
    

упаковка данных в структуре

13 minutes ago, natsu said:

а вот так не получается. Правда одна из ошибок исчезает, если в конце структуры добавить char pad[8]; но как то не выглядит это разумным.

конечно не получится, я же не знал длины Ваших структур. Надо так:

 

typedef struct
{ double energy[2][3];
  uint16_t mask;
  char pad1[6];
} zagprof_t;

typedef struct
{ uint32_t stamp;
  float data[16];
  char pad1[4];
} datprof_t;

struct my
{ double ennow[2][3];
  datprof_t dat;
  zagprof_t zag;
};

 

хотя я бы эти все структуры раскрыл бы (если это конечно возможно) и съэкономил бы 8 байт:

struct my
{ double ennow[2][3];
  double energy[2][3];
  float data[16];
  uint32_t stamp;
  uint16_t mask;
  char pad1[2];
};

 

 

Share this post


Link to post
Share on other sites

30 минут назад, natsu сказал:

typedef struct {double energy[2][3];uint16_t mask;} __attribute__((packed)) zagprof_t;

Интересно: пытаетесь экономить отдельные такты, но при этом у вас полно double. И это при том, что использовать собираетесь возможно на МК без double-FPU. Это как-то нестыкуется между собой... :wacko2:

Экономия на спичках?

Заменить один double на что-то более адекватное задаче и используемому CPU и.... глядишь и не нужно будет задумываться об отдельных тактах, теряемых на выравнивании.  :unknw:

 

PS: Просто наблюдение.

Share this post


Link to post
Share on other sites

6 minutes ago, jcxz said:

Экономия на спичках?

Скорее "из пушки по воробьям" :hunter:

Share this post


Link to post
Share on other sites

57 минут назад, natsu сказал:

typedef struct {double energy[2][3];uint16_t mask;} __attribute__((packed)) zagprof_t;
typedef struct {uint32_t stamp;float data[16];} __attribute__((packed)) datprof_t;

Странно, у меня не воспроизводятся ваши warning-и.

Share this post


Link to post
Share on other sites

похоже суть первых сообщений потерялась...

 

Данные хранятся в упакованном виде как последовательность (и массивы) структур, которые по размеру часто не кратны даже 2. Точность некоторых данных требуется минимум 8 знаков, диапазон 11 порядков (десятичных). Есть еще предварительная обработка, поэтому выбраны double - каждые от 30 до 200 отсчетов по отдельным параметрам. Промежуточные данные float. Мне кажется, я с трудом втискиваюсь в требования со своей экономией памяти, а вам так легко судить что я "экономлю на спичках". Упакованные структуры описывают данные и их sizeof соответствует реальности.

 

Для обработки данные извлекаются и помещаются в память. Чтобы не испытывать судьбу я решил считывать данные в выровненные структуры. Для обработки надо извлечь несколько структур. Поэтому мне понадобилась - желательно одна - структура в которой описаны те самые упакованные структуры но чтоб они были выровнены по адресам (достаточно для первого элемента). Все это было сказано раньше. Самый простой случай - описанная структура my и две структуры внутри. Все получилось, но чтобы успокоить компилятор, приходится вставлять руками паддинги, причем там где они похоже не нужны. Особенно удивляет паддинг 8 байтов в конце структуры. Последние вопросы и были отсюда - что не так сделано? Раз есть предупреждения, значит есть шанс получить сюрпризы позже, так? 

Share this post


Link to post
Share on other sites

13 минут назад, natsu сказал:

Данные хранятся в упакованном виде как последовательность (и массивы) структур, которые по размеру часто не кратны даже 2. Точность некоторых данных требуется минимум 8 знаков, диапазон 11 порядков (десятичных).

Это легко реализуемо на целочисленном 64-битном. На u64 запросто 19шт. 10-чных порядков.

Цитата

Есть еще предварительная обработка, поэтому выбраны double - каждые от 30 до 200 отсчетов по отдельным параметрам. Промежуточные данные float. Мне кажется, я с трудом втискиваюсь в требования со своей экономией памяти, а вам так легко судить что я "экономлю на спичках".

Вопрос не в памяти, а в скорости. Вы же с этого начали насколько помню? Программная эмуляция одной double-операции: это думаю потребует нескольких сотен тактов CPU. Невыровненный доступ к этому значению - всего +2...3 такта. Разницу ощущаете?

А если уж завели речь об экономии памяти, то её тоже можно сэкономить. И на целочисленных данных это сделать много проще: создать не 8-байтный, а 7-байтный тип данных (его вполне хватит для ваших 11 разрядов). И, из-за того что ваши кадры станут меньш размером, то и общая скорость работы тоже вырастет.

Цитата

Для обработки надо извлечь несколько структур. Поэтому мне понадобилась - желательно одна - структура в которой описаны те самые упакованные структуры но чтоб они были выровнены по адресам (достаточно для первого элемента).

Повторю ещё раз: для однократной обработки (одна-две чтения значения и примерно столько же записей) - лучше работать прямо с невыровненными данными. Все ваши "извлечения" в сумме только ухудшат скорость работы.

 

PS: Вы боретесь с "ветряными мельницами".  :unknw:

Share this post


Link to post
Share on other sites

6 hours ago, jcxz said:

PS: Вы боретесь с "ветряными мельницами".  :unknw:

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

 

ТС шифруется не рассказывая что за способы доступа и что за камень, это конено большой камень в его огород. Но, в то же время, я его прекрасно понимаю. У меня банально по DMA считывание с двух каналов с оцифровщика (по 1.3МГц на каждом) и пересохранение во внешнюю PSRAM на IMXRT1062 если делать абы как, то отъедает почти 100% ресурсов процессора, а если сделать по уму, то отъедет только 30% процессорного времени, и остаток я могу пользовать на всякую остальную всячину.

 

6 hours ago, natsu said:

Особенно удивляет паддинг 8 байтов в конце структуры.

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

Share this post


Link to post
Share on other sites

44 минуты назад, iiv сказал:

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

Это если неправильно объявить указатель. Если указатель будет объявлен как указатель на упакованные невыровненные данные, то вменямый компилятор должен сгенерить код из инструкций чтения/записи, умеющих работать с невыровненными данными.

По-крайней мере IAR, если ему указать, что u64-значение - __packed, никогда не использует для него LDRD/STRD. И прекрасно работает с невыровненными данными. И для double думаю аналогично - сгенерит пару LDR/STR.

Так что всё-таки - ветряные мельницы.  :unknw:

Цитата

У меня банально по DMA считывание с двух каналов с оцифровщика (по 1.3МГц на каждом) и пересохранение во внешнюю PSRAM на IMXRT1062 если делать абы как, то отъедает почти 100% ресурсов процессора, а если сделать по уму, то отъедет только 30% процессорного времени, и остаток я могу пользовать на всякую остальную всячину.

Какие-то странные у вас показатели... 1.3МГц - это частота чего? Какая разрядность данных?

Такая загрузка, только на перекачку, без обработки(!), при использовании DMA, выглядит несуразно большой. Даже 30%.

Хотя - может у Вас тактовая CPU всего 16МГц?  :biggrin:

Share this post


Link to post
Share on other sites

33 минуты назад, iiv сказал:

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

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

И не шифруюсь я вовсе, яж написал какой камень, конкретнее stm32f746. Но это на макете. В серии может быть чтото другое.

 

А что касается целочисленной обработки - сам так хотел. Но не склеивается.. Все равно отдельно хранить целую точную часть (смещение) и массив измененных данных. Так в массиве проще хранить float, а для точной части можно либо int либо double, второе выглядит пока проще.

Share this post


Link to post
Share on other sites

2 hours ago, jcxz said:

Такая загрузка, только на перекачку, без обработки(!), при использовании DMA, выглядит несуразно большой. Даже 30%.

не, почему же, пишем большими буферами по 64КБайта с оцифровщика по DMA, а на фоне этого делаем с зачитанных данных псевдослучайный доступ и пересохраняем это побайтово в PSRAM, реально на 240МГц в экономном по току режиме все просто лежит, так как кеш дергается на каждом обращении к каждому байту, а это с пару десятков тактов. И данных по 5МБайт в секунду (два канала по 1.3МГц и 12 бит), вот и больше сотни тактов из 240 в микросекунду потратили.

 

2 hours ago, natsu said:

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

А разве мой вариант, что я писал

typedef struct
{ double energy[2][3];
  uint16_t mask;
  char pad1[6];
} zagprof_t;

typedef struct
{ uint32_t stamp;
  float data[16];
  char pad1[4];
} datprof_t;

struct my
{ double ennow[2][3];
  datprof_t dat;
  zagprof_t zag;
};

у вас не заработал? И что пишет?

Share this post


Link to post
Share on other sites

9 часов назад, iiv сказал:

не, почему же, пишем большими буферами по 64КБайта с оцифровщика по DMA, а на фоне этого делаем с зачитанных данных псевдослучайный доступ и пересохраняем это побайтово в PSRAM, реально на 240МГц в экономном по току режиме все просто лежит, так как кеш дергается на каждом обращении к каждому байту, а это с пару десятков тактов. И данных по 5МБайт в секунду (два канала по 1.3МГц и 12 бит), вот и больше сотни тактов из 240 в микросекунду потратили.

У Вас общий поток в ОЗУ = 1.3*2*2 = 5.2 МБ/сек? Всего??? На 240МГц и Cortex-M7???  :shok:

Если так, то это просто крохи. Если что.

Для справки: У меня в текущем проекте работают 4 АЦП (12-разрядных, на 2MS/s каждый). С общим суммарным потоком в ОЗУ = 4 МБ/сек. Почти такой же поток. Только у меня Cortex-M4 на 144МГц + это не просто поток, а поток с последующей обработкой полученных данных. Всех полученных данных. И общая загрузка CPU при этом = 8.6%. И это при том что МК параллельно ещё и другие задачи выполняет (общается через TCP-сокет и т.п.). Чистая загрузка CPU только на приём/обработку этого потока ориентировочно = ~8.2%.

 

PS: Так что, как я уже говорил - ищите у себя в коде причины почему у вас работает так криво.  :unknw:

Share this post


Link to post
Share on other sites

11 часов назад, iiv сказал:

А разве мой вариант, что я писал

typedef struct
{ double energy[2][3];
  uint16_t mask;
  char pad1[6];
} zagprof_t;

размер неверный.

Share this post


Link to post
Share on other sites

1 hour ago, jcxz said:

Если так, то это просто крохи. Если что.

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

 

А так, я сейчас по DMA на 50МГц по 16 бит собираю (то есть 100МБайт/с трафик), и еще время на вычисления остается (правда уже на 600МГц), но это уже с адекватной оптимизацией по доступу к памяти.

 

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

1 minute ago, natsu said:

размер неверный.

странно, все вроде кратно восьми получается, а кто кстати так ругается? Тогда попробуйте

typedef struct
{ double energy[2][3];
  uint16_t mask, pad1, pad2, pad3;
} zagprof_t;

 

Share this post


Link to post
Share on other sites

именно восьми. А вообще то в жизни 50 байт. 

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

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

Edited by natsu

Share this post


Link to post
Share on other sites

26 минут назад, natsu сказал:

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

Чем мой вариант описания не устраивает?

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...