|
Странное предупреждение |
|
|
|
Jun 5 2018, 05:52
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Есть такая строчка в коде Код for (i=0; i < size_to_take; i++) { DataBuffer[i] = (data_out[j++]<<8) | data_out[j++]; } Выскакивает предупреждение Цитата Warning[Pa079]: undefined behavior: variable "j" (declared at line 176) (or a value reached by some form of indirection through it) is modified more than once without an intervening В GCC компайлере такого предупреждения нет.Что надо переделать чтоб предупреждение исчезло?
|
|
|
|
|
 |
Ответов
|
Jun 20 2018, 07:19
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата(Jenya7 @ Jun 5 2018, 10:52)  Есть такая строчка в коде Код for (i=0; i < size_to_take; i++) { DataBuffer[i] = (data_out[j++]<<8) | data_out[j++]; } если нет перевёртывания с эндианами и DataBuffer - это 16-ти разрядное, то Код memcpy((void*)DataBuffer, (void*)&data_out[j], 2*size_to_take); j += 2*size_to_take; //если j дальше не нужно, удалить эту строку без ворнингов, безопаснее, и БЫСТРЕЕ. (явное преобразование к воид не обязательно).
|
|
|
|
|
Jun 21 2018, 04:24
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата(Obam @ Jun 20 2018, 23:49)  GCC не ругнётся нигде и никогда: у ТСа IAR  2 Obam, читаем ещё раз первый пост ТС до конца Цитата В GCC компайлере такого предупреждения нет. Цитата Причём вообще в данном примере memcpy()? ...если ТС судя по всему пытается поменять байты местами при перемещении из источника в приёмник? С чего Вы вообще взяли, что DataBuffer имеет размерность 16 бит, а data_out - 8 бит? Причём там вообще memcpy()??? Научитесь читать исходники! adnega - ППКС, 2jcxz - из кода видно, что с вероятностью близкой к 100, данные из какого-то байтового тх/рх буфера перекидываются в нужный массив DataBuffer. Научитесь читать исходники!. Но не факт что это так, поэтому я сразу написал Цитата если нет перевёртывания с эндианами и DataBuffer - это 16-ти разрядное, то 2jcxz - Научитесь читать посты участников. Цитата мало ли чего человек хочет? Может ему требуется читать из источника пары байт и записывать их по адресу назначения с расширением до 32-бит. Не задумывались? Может быть! Согласен. Может data_out - это класс, а операторы << и | перегруженны. Может даже оператор "++" перегружен в "--". Может где то false переопределён в true. Но из кода видно, что с большей вероятностью просто перекачка из 8 бит массива в 16 битный, поэтому я и сделал оговорку. Что касается memcpy() и остального.... Цитата И я знаю как внутри работает memcpy() Как вы можете знать, как работает memcpy() у ТС, если memcpy реализуется разработчиками каждого компилятора под каждую архитектуру? Вы знаете как каждый memcpy() реализован? У каждого своя реализация. Как правило, memcpy() реализован так, что из всех возможных реализаций код memcpy будет самый оптимальный, вплоть до ухода в асм. Если пользователь компилятора/библиотеки и решит написать свой копипаст, то он будет менее эффективный, в лучшем случае будет такойже, поэтому при копировании памяти не нужно замарачиваться и изобретать скоростной велосипед, а просто использовать memcpy(). Наверно бывают случаю, что memcpy сырой, написан индусами и можно свой написать оптимальней, но это на столько редко.... и нужно хорошо знать архитектуру. Потратите много времени, выиграете 1-2 такта на копировании 1 байта.более того, если ЕСЛИ всё же нет перевертывания и это 8 и 16 бит, то даже плохой memcpy будет быстрее кода ТС. Посмотрите сколько лишних операций в for у ТС! какие-то приведения типов, операторы, << и |, дополнительный j, операции j++!!! УЖАС!!!(кстати.... j++ достаточно медленный, по сравнению с ++j). Более того, если ЕСЛИ data_out - это signed char или int8_t, то в коде ТС ошибка, которая обнаружиться только при выполнении, и хорошо если на столе ТС, а может и через год-два у пользователя. jcxz я сюда не батлится с вами захожу, я тут черпаю чужой опыт, делюсь своим и чужим опытом. Поделитесь вы..... Цитата Поэтому он будет быстрее только в определённых случаях. В каких случаях? Цитата Вы в своём совете с memcpy() допустили пару неточностей. какие неточности? Опять же, mне на батл пофиг, просто я не хочу ошибаться и других вводить в заблуждение в отличие от некоторых Или вы пустослов? Тогда можно нужно отфильтровать ваши посты, ибо это всё равно что "на заборе написано". ps вы сами себе противоречите, причем сразу в одном посте..... Цитата ТС судя по всему пытается поменять байты местами при перемещении из источника в приёмник... С чего Вы вообще взяли, что DataBuffer имеет размерность 16 бит, а data_out - 8 бит? так всё таки "ТС ... пытается поменять байты" или "С чего Вы вообще взяли, что ... data_out - 8 бит?" С чего вы решили, что я утверждаю, что DataBuffer 16 бит, а data_out - 8 бит? Я писал ЕСЛИ, вы знаете значение слова "если"?
|
|
|
|
|
Jun 21 2018, 07:05
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(juvf @ Jun 21 2018, 07:24)  Как вы можете знать, как работает memcpy() у ТС, если memcpy реализуется разработчиками каждого компилятора под каждую архитектуру? Вы знаете как каждый memcpy() реализован? У каждого своя реализация. "из кода видно, что с вероятностью близкой к 100..." где-то я это уже слышал недавно? Так вот - у ТС-а IAR, и я им пользуюсь; у ТС-а (согласно строки выше) Cortex-M - и я под него сейчас отлаживаю. Аргументов достаточно? Цитата(juvf @ Jun 21 2018, 07:24)  Как правило, memcpy() реализован так, что из всех возможных реализаций код memcpy будет самый оптимальный, вплоть до ухода в асм. Если пользователь компилятора/библиотеки и решит написать свой копипаст, то он будет менее эффективный, в лучшем случае будет такойже, поэтому при копировании памяти не нужно замарачиваться и изобретать скоростной велосипед, а просто использовать memcpy(). С этим категорически не согласен! Попробуйте когда-нить не теоретизировать внустую, а скомпилировать и посмотреть разные варианты с копированием в цикле на разных компиляторах с включённой полной оптимизацией по скорости и с разными условиями цикла (короткий цикл/длинный, условия окончания и указатели - переменные или известны на этапе компиляции). И будете удивлены. Вариант с memcpy() на коротких циклах, где кол-во проходов и/или указатели заданы переменными, проиграет варианту с простым for, так как ему не надо: a) сохранять содержимое из scratch регистров; б) делать вызов memcpy() и возврат; в) внутри memcpy() выполнять ветвление выбирая нужный вариант цикла копирования по условию длины цикла, выравниваний первого и второго аргумента и т.п. На циклах с заранее (на этапе компиляции) известными условиями выполнения, for-вариант опять же будет как минимум не хуже, просто хотя-бы потому что компилятор зная условия выполнения цикла может подставить нужную последовательность команд (подобную оптимальному копированию внутри memcpy()), но с другими более удобными регистрами и их количеством - удобными для данной точки кода. А некоторые компиляторы, так и вообще цикл for так оптимизируют (при определённых условиях) что готовому memcpy() и не снилось - в разы быстрее по скорости. Смотрим на компиляторы для DSP-ядер. Цитата(juvf @ Jun 21 2018, 07:24)  Посмотрите сколько лишних операций в for у ТС! какие-то приведения типов, операторы, << и |, дополнительный j, операции j++!!! УЖАС!!! И что? Современные оптимизаторы творят чудеса. И им по-барабану Ваши жалкие потуги заменить операции индексирования на указатели и подобное - они это и сами хорошо делают, даже ещё и лучше. Так что если бы код автора не был такой кривой, результат работы оптимизирующего компилятора мог быть лучше memcpy(). Я в своё время, разрабатывая для DSP, немало заменил копирований через memcpy() на циклы for - это давало внушительный прирост скорости. Цитата(juvf @ Jun 21 2018, 07:24)  (кстати.... j++ достаточно медленный, по сравнению с ++j). Опять чушь! Если предположить, что автор использует ARM, то что пре- что пост-инкремент - без разницы, и то и другое на ARM можно сделать в пределах одной команды выборки из памяти. Откройте мануал по системе команд и найдите разницу между: LDRB Rx, [Ry], #1 и LDRB Rx, [Ry, #1]!Цитата(juvf @ Jun 21 2018, 07:24)  В каких случаях? какие неточности? Во-первых: memcpy там не к месту как я писал выше; во-вторых: ничего не известно о значении size_to_take, а если она перед началом цикла может быть отрицательной (и i - тоже знаковое), что будет с вашим вариантом на memcpy()? в-3-х: с чего Вы приводите входные аргументы к типу void *? А если у ТС-а DataBuffer и data_out объявлены к примеру с модификатором volatile, т.е. указывают на strong ordered memory? Например DataBuffer или data_out - это FIFO-буфера в некоей периферии, чувствительные к размерности и последовательности операций записи/чтения. Я уж не говорю о том, что эта память может позволять только доступы определённой разрядности... Цитата(juvf @ Jun 21 2018, 07:24)  вы сами себе противоречите, причем сразу в одном посте..... В чём именно противоречие?  Цитата(adnega @ Jun 21 2018, 08:32)  Если по исходнику понятно, что источник шире 8 байт приведет к перемешиванию бит, а в приемнике в итоге получается только 16 значащих бит, то с уверенностью можно принять за факт их размеры 8 и 16 бит соответственно, и при необходимости заявлять "сам дурак", Из "исходника" даже не ясно, что именно нужно этому горе-программисту (если data_out указывает на unsigned char) - поменять местами байты при копировании или может он хочет продублировать байты. Т.е. сделать так: 1. *(u16 *)&DataBuffer[i] = __REVSH(*(u16 __packed *)&data_out[j]); j += 2;или так: 2. *(u16 *)&DataBuffer[i] = (uint)*(u8 *)&data_out[j++] * 0x101u;а может и что другое.....
|
|
|
|
|
Jun 22 2018, 05:11
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата(jcxz @ Jun 21 2018, 12:05)  Цитата(juvf @ Jun 21 2018, 09:24)  Посмотрите сколько лишних операций в for у ТС! какие-то приведения типов, операторы, << и |, дополнительный j, операции j++!!! УЖАС!!!
И что? Современные оптимизаторы творят чудеса. И им по-барабану Ваши жалкие потуги заменить операции индексирования на указатели и подобное - они это и сами хорошо делают, даже ещё и лучше. Так что если бы код автора не был такой кривой, результат работы оптимизирующего компилятора мог быть лучше memcpy(). Цитата Цитата Попробуйте когда-нить попробую обязательно. Добрый день фантазёры, эльфы, а также программисты. Совсем недавно (2017-2018 год) занимался оптимизацией кода в STM8. Ручные потуги оптимизации давали очень хороший результат. Оптимизатор конечно оптимизировал код, но некоторый несложный рефакторинг давал значительно лучший результат. Может стм8 сырой? может арм действительно рулит? Проверил на арме.... собрал код ТС, улучшенный код ТС, а также просто memcpy(). В трёх случаях заполнял массив uin16_t [16] из массива uin8_t[32]. Измерял осциллографом. улучшенный код ТС выглядит так: Код #define SIZ 32 uint8_t dataOut[SIZ+2]; uint16_t buffer[SIZ/2]; uint8_t *p1 = (uint8_t*)buffer; uint8_t *p2 = (uint8_t*)&dataOut[0]; ... GPIO_SetBits(GPIOA, GPIO_Pin_5); //ТР2 = 1 //оптимизированный варинат ТС for(int i = 0; i < SIZ; i++) p1[i] = p2[i]; GPIO_ResetBits(GPIOA, GPIO_Pin_5); Результат - (код TC с "<<", "|", "++", "j") / (улучшенный код ТС) / ( говноmemcpy() ) Не оптимизированный код дал результат 8/5/1.3 мкс с оптимизацией по скорости -Ohs результат 3/0.5/0.5 мкс кагбэ в примере всё выровнено к 4. Но серийные данные не всегда выровнены, поэтому усложнил задачу МК и приблизил к реальности, uint8_t *p2 = (uint8_t*)&dataOut[1]; получил без оптимизациии 8/5/2мкс, с оптимизацией -Ohs 3/2/1.7 мск Результат на лицо. Априори. Вот вам и наряд в не очереди современные оптимизаторы!!! ps проверял на стм32ф103, компилятор иар.
|
|
|
|
Сообщений в этой теме
Jenya7 Странное предупреждение Jun 5 2018, 05:52 scifi j++ два раза в одном выражении - это бяка. Результ... Jun 5 2018, 05:54 Jenya7 Цитата(scifi @ Jun 5 2018, 11:54) j++ два... Jun 5 2018, 05:58 MrYuran Цитата(scifi @ Jun 5 2018, 08:54) j++ два... Jun 5 2018, 06:18 scifi Цитата(Jenya7 @ Jun 5 2018, 08:58) по мое... Jun 5 2018, 06:37 andrew_b Цитата(scifi @ Jun 5 2018, 09:37) То есть... Jun 5 2018, 06:49  scifi Цитата(andrew_b @ Jun 5 2018, 09:49) Риск... Jun 5 2018, 07:09   andrew_b Цитата(scifi @ Jun 5 2018, 10:09) Неверно... Jun 5 2018, 13:24    Сергей Борщ QUOTE (andrew_b @ Jun 5 2018, 16:24) Оно?... Jun 5 2018, 15:22 MrYuran Цитата(scifi @ Jun 5 2018, 09:37) То есть... Jun 5 2018, 07:07 Jenya7 Цитата(scifi @ Jun 5 2018, 12:37) Что меш... Jun 5 2018, 08:17 ViKo А вот же похожая тема. Только в ней инкремент с др... Jun 5 2018, 07:34 k155la3 Код DataBuffer[i] = (data_out[j++... Jun 5 2018, 12:55 scifi Цитата(juvf @ Jun 20 2018, 10:19) без вор... Jun 20 2018, 08:59   jcxz Цитата(juvf @ Jun 20 2018, 13:10) Bера в ... Jun 20 2018, 10:24    juvf Цитата(jcxz @ Jun 20 2018, 15:24) но даже... Jun 20 2018, 10:37     jcxz Цитата(juvf @ Jun 20 2018, 13:37) какую?
... Jun 20 2018, 18:30      adnega Цитата(jcxz @ Jun 20 2018, 21:30) С чего ... Jun 20 2018, 18:42       jcxz Цитата(adnega @ Jun 20 2018, 21:42) Это о... Jun 20 2018, 19:31        adnega Цитата(jcxz @ Jun 20 2018, 22:31) И что? ... Jun 20 2018, 20:01   adnega Цитата(juvf @ Jun 20 2018, 13:10) C memcp... Jun 20 2018, 10:31     adnega Цитата(juvf @ Jun 21 2018, 07:24) С чего ... Jun 21 2018, 05:32      Сергей Борщ QUOTE (adnega @ Jun 21 2018, 08:32) ... Jun 21 2018, 06:22       VladislavS Цитата(Сергей Борщ @ Jun 21 2018, 09:22) ... Jun 21 2018, 07:27       scifi Цитата(juvf @ Jun 22 2018, 08:11) Добрый ... Jun 22 2018, 06:55       jcxz Цитата(juvf @ Jun 22 2018, 08:11) ps пров... Jun 22 2018, 07:37        juvf ваш ответ - тоже априори. много слюней, воды, теле... Jun 22 2018, 09:13         jcxz Цитата(juvf @ Jun 22 2018, 12:13) Нормаль... Jun 22 2018, 09:31          juvf Цитата(jcxz @ Jun 22 2018, 14:31) Ну, дае... Jun 22 2018, 18:10 scifi Цитата(juvf @ Jun 20 2018, 10:19) и БЫСТР... Jun 20 2018, 12:52 VladislavS Цитата(scifi @ Jun 20 2018, 15:52) Интере... Jun 20 2018, 17:59 juvf ну на конец то предметный разговор, а не "сле... Jun 21 2018, 07:50 scifi Цитата(juvf @ Jun 21 2018, 10:50) Но, во ... Jun 21 2018, 08:03  juvf Цитата(scifi @ Jun 21 2018, 13:03) За так... Jun 21 2018, 08:17 jcxz Цитата(juvf @ Jun 21 2018, 10:50) Морите... Jun 21 2018, 08:41 scifi Цитата(juvf @ Jun 21 2018, 10:50) Или по ... Jun 21 2018, 08:42 jcxz Цитата(juvf @ Jun 21 2018, 10:50) Но, во ... Jun 21 2018, 08:44  juvf ЦитатаПродолжаем думать дальше. Подсказываю ещё ра... Jun 21 2018, 09:01   scifi Цитата(juvf @ Jun 21 2018, 12:01) Такой к... Jun 21 2018, 09:07    juvf Цитата(scifi @ Jun 21 2018, 14:07) Конечн... Jun 21 2018, 09:24   jcxz Цитата(juvf @ Jun 21 2018, 12:01) Что за ... Jun 21 2018, 10:18    juvf Цитата(jcxz @ Jun 21 2018, 14:53) Где это... Jun 21 2018, 10:24     jcxz Цитата(juvf @ Jun 21 2018, 13:24) ээээ...... Jun 21 2018, 11:06      scifi Цитата(jcxz @ Jun 21 2018, 14:06) И по ас... Jun 21 2018, 11:09      juvf Цитата(jcxz @ Jun 21 2018, 16:06) При пер... Jun 21 2018, 11:19    adnega Цитата(jcxz @ Jun 21 2018, 13:09) В приве... Jun 21 2018, 10:25     jcxz Цитата(adnega @ Jun 21 2018, 13:25) компи... Jun 21 2018, 11:12      scifi Цитата(jcxz @ Jun 21 2018, 14:10) Для так... Jun 21 2018, 11:13       jcxz Цитата(scifi @ Jun 21 2018, 14:13) Пожалу... Jun 21 2018, 11:22      adnega Цитата(jcxz @ Jun 21 2018, 14:12) Из Ваше... Jun 21 2018, 12:01    juvf Цитата(jcxz @ Jun 21 2018, 15:18) При отл... Jun 21 2018, 10:50     scifi Цитата(juvf @ Jun 21 2018, 13:50) inline ... Jun 21 2018, 11:04     jcxz Цитата(juvf @ Jun 21 2018, 13:50) У меня ... Jun 21 2018, 11:19      juvf Цитата(jcxz @ Jun 21 2018, 16:19) Ведь ес... Jun 21 2018, 11:46       jcxz Цитата(juvf @ Jun 21 2018, 14:46) в waitS... Jun 21 2018, 12:11        adnega Цитата(jcxz @ Jun 21 2018, 15:11) PS: Есл... Jun 21 2018, 12:57        juvf Цитата(jcxz @ Jun 21 2018, 17:11) Вот так... Jun 21 2018, 13:09         scifi Цитата(juvf @ Jun 21 2018, 16:09) Дело в ... Jun 21 2018, 13:19          juvf ЦитатаПравильно тут уже написали про Ваш стиль: Вм... Jun 21 2018, 14:44         adnega Цитата(juvf @ Jun 21 2018, 16:09) Т.е. по... Jun 21 2018, 13:34          scifi Цитата(adnega @ Jun 21 2018, 16:34) Телеп... Jun 21 2018, 13:40           adnega Цитата(scifi @ Jun 21 2018, 16:40) А не л... Jun 21 2018, 13:56     jcxz Цитата(juvf @ Jun 21 2018, 13:50) inline ... Jun 21 2018, 11:48      juvf Цитата(jcxz @ Jun 21 2018, 16:48) описани... Jun 21 2018, 12:29       scifi Цитата(juvf @ Jun 21 2018, 15:29) CS - не... Jun 21 2018, 12:39       jcxz Цитата(juvf @ Jun 21 2018, 15:29) Я же го... Jun 21 2018, 14:21        adnega Цитата(jcxz @ Jun 21 2018, 17:21) Нет, не... Jun 21 2018, 14:47  adnega Цитата(jcxz @ Jun 21 2018, 11:44) Ибо в 9... Jun 21 2018, 09:06 Kabdim Любопытства ради и самообразования для, не могли б... Jun 21 2018, 11:02 juvf Цитата(Kabdim @ Jun 21 2018, 16:02) Любоп... Jun 21 2018, 11:06 VladislavS Вместо стольких слов достаточно посмотреть листинг... Jun 21 2018, 15:52 jcxz Цитата(VladislavS @ Jun 21 2018, 18:52) В... Jun 21 2018, 16:51
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|