реклама на сайте
подробности

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> Формирование int из массива char
scifi
сообщение Feb 15 2016, 19:41
Сообщение #31


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(zltigo @ Feb 15 2016, 21:44) *
К чему в очередной раз поминание древней глупости - "преждевременная оптимизация" ?
http://electronix.ru/forum/index.php?showt...t&p=1348755

Нет времени отвечать на ваши глупости. Кто имеет уши - тот услышит.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 15 2016, 21:52
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (scifi @ Feb 15 2016, 21:41) *
Нет времени...

Не сомневался sm.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 15 2016, 23:34
Сообщение #33


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(scifi @ Feb 16 2016, 00:02) *
И это тоже. Прогресс в компиляторостроении привёл к тому, что вот эти стенания "а как же эти лишние две инструкции?" - зачастую устаревшая выдумка

Типичный аргумент кодера-форточника, создающего шедевры, способные показом обычного диалога загрузить intel-i7 на 100% на минуту.
Цитата(scifi @ Feb 16 2016, 00:02) *
Но даже не так, пара лишних тактов и байтов вредит крайне редко. Короче, "преждевременная оптимизация", если говорить без матюков, но иметь в виду именно их smile3009.gif

Предположим: нужна функция, инкрементирующая пакованный int. С __packed на Cortex-M это будет:
Код
LDR R1, [R0]
ADDS R1, R1, #1
STR R1, [R0]
BX LR

В случае с memcpy будет: создание стекового фрейма, копирование, инкремент, опять копирование, удаление стекового фрейма - итого:
не на пару байт, а во много раз (!!!) дольше + занимает доп.регистры + доп.стек.
Go to the top of the page
 
+Quote Post
scifi
сообщение Feb 16 2016, 08:36
Сообщение #34


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(jcxz @ Feb 16 2016, 02:34) *
Предположим: нужна функция, инкрементирующая пакованный int. С __packed на Cortex-M это будет:
Код
LDR R1, [R0]
ADDS R1, R1, #1
STR R1, [R0]
BX LR

Попробовал на своём Cortex-M0. Не работает crying.gif

Цитата(jcxz @ Feb 16 2016, 02:34) *
В случае с memcpy будет: создание стекового фрейма, копирование, инкремент, опять копирование, удаление стекового фрейма - итого:
не на пару байт, а во много раз (!!!) дольше + занимает доп.регистры + доп.стек.

Глупость какая. Только что попробовал на Cortex-M3: как и положено, вместо memcpy подставляет LDR/STR.

Цитата(Сергей Борщ @ Feb 15 2016, 13:43) *
А по мне так наоборот - если происходит действие "обращение по указателю" - то логично было бы использовать предусмотренные для этого в языке средства разыменования указателя, а не захламлять исходник вызовами memcpy(). То, что этот указатель учитывает какие-то аппаратные особенности (невыровненный доступ), логично было бы как-то указать один раз при объявлении указателя (тот же __packed), а не распылять по исходнику в виде memcpy() и надеяться, что программист не забудет именно этот указатель использовать через memcpy().

В gcc можно обернуть искомые данные в упакованную структуру и обращаться по указателю на эту структуру.

Наверное, всё дело в том, что мне не доводилось писать код с невыровненным доступом, потому и удивляюсь. А ради одного-двух случаев в коде я точно не стал бы городить packed, а сделал бы memcpy. Хотя могу представить себе такой код - lwip, к примеру. Там нужно постоянно обращаться к полям пакетов, и там повсеместно используются упакованные структуры. Альтернатива - сделать функции доступа к полям через указание смещений, но это точно будет выглядеть коряво на фоне упакованных структур, так что принято.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 16 2016, 10:52
Сообщение #35


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (scifi @ Feb 16 2016, 10:36) *
Наверное, всё дело в том, что мне не доводилось писать код с невыровненным доступом, потому и удивляюсь.

Практически абсолютно любой протокол обмена требует обращения ко всяким разным полям (в том числе и битовым )во фрейме, то что они не выровнееные это практически наверняка и если не писать разбоку и формирование в стиле "третий бит в пятом байте слева" (за что вообще-то надо сразу чего нибудь оторвать, что болтается), то сразу становятся необходимыми структуры и обьединения. Причем, если платформа не восьмибитовая, то сразу возникают понятия раковки стуктур и на многих платформах невыровненный доступ. Но проблема доступа в таком случае сразу скрывает компилятор.
Но в общем структуры организуются СОВЕРШЕННО не для того, что-бы бороться с выравниваним и заявление:
QUOTE
А ради одного-двух случаев в коде я точно не стал бы городить packed

более чем....


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Feb 16 2016, 11:07
Сообщение #36


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Цитата(dimka76 @ Feb 15 2016, 14:19) *
Код
typedef volatile uint32_t REG32;
#define pREG32 (REG32 *)
#define USB_TXDATA                                (*(pREG32 (0x4002001C)))

uint8_t *pData;

USB_TXDATA = *((uint32_t __attribute__((packed)) *)pData);

В тех примерах от NXP которые у меня:
Код
#if defined(__GNUC__)   // Code Red tools

...

// The following two typedefs are required as GCC does
// not directly support a method of hinting that a variable
// (as opposed to a structure) should be accessed with
// the assumption that it is unaligned, which can be done
// in Keil using, for example, __packed uint32_t *p;
typedef struct { uint32_t value __attribute__(( packed ));
}unaligned_uint32;

typedef struct { uint16_t value __attribute__(( packed ));
}unaligned_uint16;

...

А использование что-то вроде такого:
Код
#if defined(__GNUC__)
          (( unaligned_uint16 *)EP0Buf)->value = (USB_EndPointHalt & m) ? 1 : 0;;
#else
          *((__packed uint16_t *)EP0Buf) = (USB_EndPointHalt & m) ? 1 : 0;
#endif
Go to the top of the page
 
+Quote Post
scifi
сообщение Feb 16 2016, 11:32
Сообщение #37


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Kabdim @ Feb 16 2016, 14:07) *
А использование что-то вроде такого:
Код
#if defined(__GNUC__)
          (( unaligned_uint16 *)EP0Buf)->value = (USB_EndPointHalt & m) ? 1 : 0;;
#else
          *((__packed uint16_t *)EP0Buf) = (USB_EndPointHalt & m) ? 1 : 0;
#endif

Интересно, зачем так? Ведь гнусишный вариант вполне может работать и с RealView.
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Feb 16 2016, 12:15
Сообщение #38


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Цитата(scifi @ Feb 16 2016, 14:32) *
Интересно, зачем так? Ведь гнусишный вариант вполне может работать и с RealView.

Там были глупостей и ошибки похлеще, но работало. Подозреваю что вначале написали на Кейле, а потом другой человек отпортировали на gcc не слишком задумываясь, лишь бы работало.

Сообщение отредактировал Kabdim - Feb 16 2016, 12:33
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 16 2016, 13:08
Сообщение #39


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(jcxz @ Feb 16 2016, 02:34) *
В случае с memcpy будет: создание стекового фрейма...
Такого ужаса уже давно нет.
По крайней мере, в gcc практически все библиотечные функции за'builtin'ены, и компилятор встраивает и разворачивает их максимально гибко, вплоть до того, что sin(const) и иже с ним считается чуть-ли не на этапе препроцессинга и может использоваться даже для инициализации констант.

Цитата(Kabdim @ Feb 16 2016, 14:07) *
Код
          typedef struct { uint16_t value __attribute__(( packed ));}unaligned_uint16_t;

          (( unaligned_uint16_t *)EP0Buf)->value = 1;
С выкрутасом решение, но читаемость хромает.
Если запрятать это в макрос, то читаемость поднимется в разы...
Спасибо! Может когда-нибудь пригодится.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 16 2016, 13:59
Сообщение #40


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(demiurg_spb @ Feb 16 2016, 19:08) *
Такого ужаса уже давно нет.
По крайней мере, в gcc практически все библиотечные функции за'builtin'ены, и компилятор встраивает и разворачивает их максимально гибко, вплоть до того, что sin(const) и иже с ним считается чуть-ли не на этапе препроцессинга и может использоваться даже для инициализации констант.

Часто приходится компилить без оптимизации, для отладки и т.п. С отключенной оптимизацией разве развернёт?
Один фиг - писать все эти memcpy() для доступа к одной пакованной переменной - это как раз глупо и слишком громоздко (снижает читаемость исходника).
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 16 2016, 14:30
Сообщение #41


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(jcxz @ Feb 16 2016, 16:59) *
Часто приходится компилить без оптимизации, для отладки и т.п. С отключенной оптимизацией разве развернёт?
Не знаю, т.к. меня этот вопрос вообще не заботит.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Tarbal
сообщение Feb 16 2016, 14:31
Сообщение #42


Профессионал
*****

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



Цитата(AlexeyT @ Feb 12 2016, 18:05) *
Задача такая - есть массив test_buff, из подряд идущих 4-х элементов которого нужно сформировать переменную unsigned int.

unsigned char test_buff[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
unsigned char *tst_point = &test_buff[0];
unsigned int *tst;

tst = (unsigned int *)(tst_point + 2*sizeof(unsigned char)); //должны получить 0x06050403 = 100992003

Т.е. в *tst пытаюсь записать unsigned int, состоящий из байтов массива с 3-го по 6-й.

При исполнении этого кода на ARM-процессоре (ядро Cortex-M1) происходит зависание ядра (когда обращаюсь к адресу, некратному 4 байтам).
При исполнении этого же кода на ПК - все ок, *tst = 100992003, как и должно быть.
Компилятор Keil.

Есть идеи, как решить задачу?


А ваш процессор Big endian или little endian? Вроде в АРМ это переключить можно, хотя чаще всего он он little endian.
Второй вопрос в вашем массиве данные Big endian или little endian?
Go to the top of the page
 
+Quote Post
_pv
сообщение Feb 16 2016, 18:33
Сообщение #43


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(jcxz @ Feb 16 2016, 19:59) *
Один фиг - писать все эти memcpy() для доступа к одной пакованной переменной - это как раз глупо и слишком громоздко (снижает читаемость исходника).

ради одной пакованной переменной писать кучу #if при объявлении, с различными прагмами/атрибутами для разных компиляторов не менее глупо.
лучше уж макрос или инлайн функция которая возвращает нормальный int из невыровненного адреса.

в единственном случае где могут понадобится упакованные структуры и где без этого вполне можно обойтись - в случае с протоколами обмена, там всё равно все доступы к структуре будут обёрнуты в hton / ntoh. ну будет еще одна обёртка для выравнивания, тоже мне проблема.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 16 2016, 19:16
Сообщение #44


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (_pv @ Feb 16 2016, 20:33) *
ради одной пакованной переменной писать кучу #if при объявлении, с различными прагмами/атрибутами для разных компиляторов не менее глупо.
лучше уж макрос или инлайн функция которая возвращает нормальный int из невыровненного адреса.

Городить какую-то функцию, которая будет разбитаться как именно невыровнен адрес а может и выровнен.... тода уж memcpy() - эта занимается тем-же самым, но понятно, что делает.
И все это ради того, что-бы отвергать великолепный механизм паковки и доступа к структурам. Дурдом. Но понятный после этого заявления:
QUOTE
в единственном случае где могут понадобится упакованные структуры и где без этого вполне можно обойтись - в случае с протоколами обмена

становится понятным, что задачи обмена данными бесконечно далеки от Вас и "контроллеров светодиодов".
QUOTE
, там всё равно все доступы к структуре будут обёрнуты в hton / ntoh.

C какого бодуна, если это зависит от протокола и контрорлера.



--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
_pv
сообщение Feb 16 2016, 20:16
Сообщение #45


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(zltigo @ Feb 17 2016, 01:16) *
Городить какую-то функцию, которая будет разбитаться как именно невыровнен адрес а может и выровнен.... тода уж memcpy() - эта занимается тем-же самым, но понятно, что делает.
И все это ради того, что-бы отвергать великолепный механизм паковки и доступа к структурам. Дурдом.

Этот великолепный механизм - костыли которые в каждом компиляторе сделаны (и хорошо если в каждом) по своему.
Вон у TI, TCP стэк для msp430, как-то обошлись без великолепных механизмов.
И раз уж Вы так близки к задачам обмена данными, не приведёте код объявления упакованной структуры который любой С компилятор поймёт?
Цитата(zltigo @ Feb 17 2016, 01:16) *
C какого бодуна, если это зависит от протокола и контрорлера.

endiannes у всех всех контроллеров вдруг стала одинаковая и так получиться так что она будет отличаться от заданной в протоколе никак не может?
Go to the top of the page
 
+Quote Post

4 страниц V  < 1 2 3 4 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th June 2025 - 19:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.01531 секунд с 7
ELECTRONIX ©2004-2016