Jump to content

    

Навык анализа листингов

49 minutes ago, jcxz said:

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

Зато данные всегда выровнены. Нет штрафа за запись по некруглому адресу. Что скорее всего перекроет расходы на TBB.

57 minutes ago, jcxz said:

Особенно касается алгоритма поиска максимума/минимума на массиве из 512 несортированных 16-разрядных чисел.

К сожалению, для IAR'а есть проблема - он принципиально не желает генерить LDM для разгрузки многих переменных. Потому самый оптимальный вариант не получится. А так intrinsic'и вполне решают задачу. Щас продемонстрирую.

Share this post


Link to post
Share on other sites

Ну допустим так:

#include <intrinsics.h>

#define PROCESS4() acc=*s++; max=__UQSUB16(max,acc)+acc; max=__UQSUB16(max,acc>>32)+(acc>>32)

unsigned long findmax(unsigned short *_s)
{
  unsigned long max=0;
  unsigned long long acc;
  unsigned long long *s=(unsigned long long *)_s;
  for(unsigned long i=0; i<512/(4*4); i++)
  {
    PROCESS4();
    PROCESS4();
    PROCESS4();
    PROCESS4();
  }
  if ((max>>16)>(max&0xFFFF)) return max>>16;
  return max&0xFFFF;
}
Spoiler

     62          unsigned long findmax(unsigned short *_s)
		     63          {
		   \                     findmax: (+1)
		   \        0x0   0xB470             PUSH     {R4-R6}
		     64            unsigned long max=0;
		     65            unsigned long long acc;
		     66            unsigned long long *s=(unsigned long long *)_s;
		     67            for(unsigned long i=0; i<512/(4*4); i++)
		   \        0x2   0x4601             MOV      R1,R0
		   \        0x4   0x2600             MOVS     R6,#+0
		   \        0x6   0x2020             MOVS     R0,#+32
		     68            {
		     69              PROCESS4();
		   \                     ??findmax_0: (+1)
		   \        0x8   0xE8F1 0x2302      LDRD     R2,R3,[R1], #+8
		   \        0xC   0xFAD6 0xF652      UQSUB16  R6,R6,R2
		   \       0x10   0x1996             ADDS     R6,R2,R6
		     70              PROCESS4();
		   \       0x12   0xE8F1 0x4502      LDRD     R4,R5,[R1], #+8
		   \       0x16   0xFAD6 0xF253      UQSUB16  R2,R6,R3
		   \       0x1A   0x18D2             ADDS     R2,R2,R3
		   \       0x1C   0xFAD2 0xF254      UQSUB16  R2,R2,R4
		   \       0x20   0x18A2             ADDS     R2,R4,R2
		   \       0x22   0xFAD2 0xF255      UQSUB16  R2,R2,R5
		   \       0x26   0x1952             ADDS     R2,R2,R5
		     71              PROCESS4();
		   \       0x28   0xE8F1 0x4502      LDRD     R4,R5,[R1], #+8
		   \       0x2C   0xFAD2 0xF254      UQSUB16  R2,R2,R4
		   \       0x30   0x18A2             ADDS     R2,R4,R2
		   \       0x32   0xFAD2 0xF255      UQSUB16  R2,R2,R5
		   \       0x36   0x1952             ADDS     R2,R2,R5
		     72              PROCESS4();
		   \       0x38   0xE8F1 0x4502      LDRD     R4,R5,[R1], #+8
		   \       0x3C   0xFAD2 0xF254      UQSUB16  R2,R2,R4
		   \       0x40   0x18A2             ADDS     R2,R4,R2
		   \       0x42   0xFAD2 0xF255      UQSUB16  R2,R2,R5
		   \       0x46   0x1956             ADDS     R6,R2,R5
		     73            }
		   \       0x48   0x1E40             SUBS     R0,R0,#+1
		   \       0x4A   0xD1DD             BNE.N    ??findmax_0
		     74            if ((max>>16)>(max&0xFFFF)) return max>>16;
		   \       0x4C   0x0C30             LSRS     R0,R6,#+16
		   \       0x4E   0xB2B6             UXTH     R6,R6
		   \       0x50   0x4286             CMP      R6,R0
		   \       0x52   0xBF28             IT       CS 
		   \       0x54   0x4630             MOVCS    R0,R6
		     75            return max&0xFFFF;
		   \       0x56   0xBC70             POP      {R4-R6}
		   \       0x58   0x4770             BX       LR               ;; return
		     76          }

Понятное дело, что развернуть можно чуть больше, если сильно надо. Основной провал по сравнению с asm-вариантом - невозможность загрузить сразу кучу переменных при помощи LDM, потому LDRD в качестве оптимизации. Но это IAR такой, насколько я знаю, GCC вроде бы умеет.

 

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

Share this post


Link to post
Share on other sites
20 minutes ago, Rst7 said:

невозможность загрузить сразу кучу переменных при помощи LDM

Если нельзя, но очень хочется - то можно:

#define PROCESS2(V) max=__UQSUB16(max,V)+V;

unsigned long findmaxv2(unsigned short *_s)
{
  unsigned long max=0;
  unsigned long a0,a1,a2,a3,a4,a5,a6,a7;
  for(unsigned long i=0; i<512/(2*8); i++)
  {
    asm("LDMIA %0!,{%1,%2,%3,%4,%5,%6,%7,%8}":
          "+r"(_s),
          "=r"(a0),"=r"(a1),"=r"(a2),"=r"(a3),
          "=r"(a4),"=r"(a5),"=r"(a6),"=r"(a7));
    PROCESS2(a0);
    PROCESS2(a1);
    PROCESS2(a2);
    PROCESS2(a3);
    PROCESS2(a4);
    PROCESS2(a5);
    PROCESS2(a6);
    PROCESS2(a7);
  }
  if ((max>>16)>(max&0xFFFF)) return max>>16;
  return max&0xFFFF;
}
Spoiler

     80          unsigned long findmaxv2(unsigned short *_s)
     81          {
   \                     findmaxv2: (+1)
   \        0x0   0xE92D 0x41F0      PUSH     {R4-R8,LR}
   \        0x4   0x4606             MOV      R6,R0
     82            unsigned long max=0;
   \        0x6   0x2700             MOVS     R7,#+0
     83            unsigned long a0,a1,a2,a3,a4,a5,a6,a7;
     84            for(unsigned long i=0; i<512/(2*8); i++)
   \        0x8   0xF05F 0x0520      MOVS.W   R5,#+32
     85            {
     86              asm("LDMIA %0!,{%1,%2,%3,%4,%5,%6,%7,%8}":
                                                            ^
Warning[Og014]: Warning in inline assembly: "Registers are not specified in
          ascending order"
     87                    "+r"(_s),
     88                    "=r"(a0),"=r"(a1),"=r"(a2),"=r"(a3),
     89                    "=r"(a4),"=r"(a5),"=r"(a6),"=r"(a7));
   \                     ??findmaxv2_0: (+1)
   \        0xC   0xE8B6 0x511F      LDMIA R6!,{R8,LR,R12,R0,R1,R2,R3,R4}
     90              PROCESS2(a0);
     91              PROCESS2(a1);
     92              PROCESS2(a2);
     93              PROCESS2(a3);
     94              PROCESS2(a4);
     95              PROCESS2(a5);
     96              PROCESS2(a6);
     97              PROCESS2(a7);
   \       0x10   0xFAD7 0xF758      UQSUB16  R7,R7,R8
   \       0x14   0x44B8             ADD      R8,R8,R7
   \       0x16   0xFAD8 0xF75E      UQSUB16  R7,R8,LR
   \       0x1A   0x44BE             ADD      LR,LR,R7
   \       0x1C   0xFADE 0xF75C      UQSUB16  R7,LR,R12
   \       0x20   0x44BC             ADD      R12,R12,R7
   \       0x22   0xFADC 0xF750      UQSUB16  R7,R12,R0
   \       0x26   0x19C0             ADDS     R0,R0,R7
   \       0x28   0xFAD0 0xF051      UQSUB16  R0,R0,R1
   \       0x2C   0x1809             ADDS     R1,R1,R0
   \       0x2E   0xFAD1 0xF052      UQSUB16  R0,R1,R2
   \       0x32   0x1812             ADDS     R2,R2,R0
   \       0x34   0xFAD2 0xF053      UQSUB16  R0,R2,R3
   \       0x38   0x181B             ADDS     R3,R3,R0
   \       0x3A   0xFAD3 0xF754      UQSUB16  R7,R3,R4
   \       0x3E   0x19E7             ADDS     R7,R4,R7
     98            }
   \       0x40   0x1E6D             SUBS     R5,R5,#+1
   \       0x42   0xD1E3             BNE.N    ??findmaxv2_0
     99            if ((max>>16)>(max&0xFFFF)) return max>>16;
   \       0x44   0x0C38             LSRS     R0,R7,#+16
   \       0x46   0xB2BF             UXTH     R7,R7
   \       0x48   0x4287             CMP      R7,R0
   \       0x4A   0xBF28             IT       CS 
   \       0x4C   0x4638             MOVCS    R0,R7
    100            return max&0xFFFF;
   \       0x4E   0xE8BD 0x81F0      POP      {R4-R8,PC}       ;; return
    101          }

 

Конечно, в реальной жизни надо подавить warning, который понятно почему возникает. И цикл минимально развернуть.

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

Share this post


Link to post
Share on other sites
7 hours ago, jcxz said:

Речь тут шла не об обсуждении моего конкретного кода

И, тем не менее, я не возражаю против отклонения:blum: Наоборот, читаю с упоением!

Share this post


Link to post
Share on other sites

Если вспомнить сам процесс "анализа листинга", то можно представить, как программист в своей памяти "рисует" ветви и циклы программы, что можно назвать "визуальным моделированием" процесса работы программы. Всё просто замечательно при наличии абсолютной памяти профессинала и желательно владением телепатическими способностями при общении с коллегами. В классике программирования изначально разрабатывлась функциональная схема программы с подробным изложением в ней всевозможных отладочных элементов для слежения за работой программы. Каждому ведущему программисту полагалось иметь не менее одного секретаря для выполнения рутинной работы. К сожалению, энтузиасту сложно доказать необходимость практически, как минимум самому себе, удвоения числа лиц допущенных ко всем "секретам" разрабатываемой программы. Поэтому уникальные "специалисты единоличники" (СЕ) типа "чиню, паяю, ЭВМ починяю и ... программирую" заполонили все форумы. И не только форумы... Достаточно вспомнить о печально известных "ошибках" в программе управления пассажирскими самолётами фирмы Боинг  и не только гражданскими...

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

Share this post


Link to post
Share on other sites
5 minutes ago, SVNKz said:

СЕ с самого начала присваивает себе "титул" абсолютного "специалиста",

Простите, а вы что сказать-то хотели?

Share this post


Link to post
Share on other sites

Хотел сказать Вам конкретно...

1. У Вас нет ТЗ на программу;

2. Вы работаете в качестве СЕ;

3. Вам необходимо за еду поработать в паре с профессионалом в качестве секретаря;

4. Все свои программы и алгоритмы оформлять в бумажном виде, конспектах;

5. Познакомится с основами работы и "правилами эксплуатации" собственного мозга.

Наверняка мои ответы  Вас удивляют... и, если чем-то задели Ваш эгоцентризм, то извините за откровенность...

Share this post


Link to post
Share on other sites
51 minutes ago, SVNKz said:

Хотел сказать Вам конкретно...

Отлично, а то изначально я не понял кому вы адресуете свой ответ)

51 minutes ago, SVNKz said:

1. У Вас нет ТЗ на программу;

Откуда такие знания? Есть ТЗ.

51 minutes ago, SVNKz said:

2. Вы работаете в качестве СЕ;

Я работаю на фирме среди других специалистов (электронщиков, программистов, настройщиков и т.п.).

51 minutes ago, SVNKz said:

3. Вам необходимо за еду поработать в паре с профессионалом в качестве секретаря;

Поработать с профессионалом согласен, но не за еду.

51 minutes ago, SVNKz said:

4. Все свои программы и алгоритмы оформлять в бумажном виде, конспектах;

Гм. Возможно, возможно, я чего-то не понимаю в этом мире. Но попробуйте оформить алгоритм и программу в бумажном виде на стек TCP/IP. Пусть это будет свободно распространяемый lwIP. Как это будет выглядеть? Некоторое документирование приветствуется. Но до какого уровня?

51 minutes ago, SVNKz said:

5. Познакомится с основами работы и "правилами эксплуатации" собственного мозга.

Подскажите источник.

51 minutes ago, SVNKz said:

Наверняка мои ответы  Вас удивляют...

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

51 minutes ago, SVNKz said:

если чем-то задели Ваш эгоцентризм, то извините за откровенность...

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

Share this post


Link to post
Share on other sites
5 минут назад, haker_fox сказал:

Подскажите источник.

 Изучение и освоение информации из этих"источников" самое сложное и важное. Доступно и понятно об этом в пишет и рассказывает д.б.н. Савельева. Фильмов с его редакцией в интернете достаточно.

Share this post


Link to post
Share on other sites
1 minute ago, SVNKz said:

 Изучение и освоение информации из этих"источников" самое сложное и важное. Доступно и понятно об этом в пишет и рассказывает д.б.н. Савельева. Фильмов с его редакцией в интернете достаточно.

Это всё, конечно, интересно. Но слив, флуд и прочие прелести засчитаны!

Share this post


Link to post
Share on other sites
18 hours ago, jcxz said:

А у меня максимальное количество одновременно включённых каналов осциллографирования от 14 до 28.

Это озвучено не было

18 hours ago, jcxz said:

Что там сложного в присваиваниях?

Запись по невыровненным адресам (в идеале нужно склеивать соседние данные и писать выровненно). Ну и возможно понадобится скедулинг команд (я не в курсе, какой у ARM Cortex конвеер)

18 hours ago, jcxz said:

Мой полиморфный код

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

 

18 hours ago, jcxz said:

> Если исходный буфер был выровненный, то некоторые запись в память можно отконвертировать из невыровненных в выровненные. (Не помню, в M4 есть запись невыровненных данных?)

Тут - не понял... 

Убрать __packed

18 hours ago, jcxz said:

Но они будут. Переходы. Как минимум - 32 штуки.

В исходном коде - 128 (если не учитывать первый пункт из этого ответа). А это ещё более дофига - в 4 раза

 

Share this post


Link to post
Share on other sites
18 hours ago, jcxz said:

Речь тут шла не об обсуждении моего конкретного кода, а о необходимости знания ассемблера как такового.

И даже не об этом. А о том, нужно ли смотреть листинги после компилятора.

В общем, как обычно, предмет спора у каждого свой, и срач уже на 5 страниц :feminist_en:

Давайте определимся, кто и что имел в виду:

Моя точка зрения:

Нужно ли всегда просматривать листинги после компилятора?

  • Если вы разработчик компилятора (всех его разновидностей, включая JIT) - да
  • Если вы performance аналитик - да
  • Если вы обычный разработчик - нет (даже категорически нет - может появится острое желание переписать всё на ассемблер, с этим надо бороться :biggrin: )

Нужно ли знать ассемблер обычному разработчику?

  • Если вы desktop (или web) разработчик - скорее всего нет
  • Если вы embedded разработчик - скорее всего да. Вы должны знать архитектуру МК, на который пишете (хотя бы поверхостно). Но если вы претендуете на звание квалифицированного разработчика вы должны знать её досконально (включая и ассемблер)

Можно ли писать программы на МК не зная его архитектуру?

  • Можно, но не нужно. К сожалению этому очень способствуют тулзы типа Cube - появляется толпа 'разработчиков', которые вообще не представляют, что стоит за этими кнопочками и менюшками. А потом раздаются крики, со всех сторон - Куб гов%;%;, давить и пр. Куб всего лишь инструмент, типа молотка. Молотком можно забивать гвозди, а можно бить себе по пальцам. Это совсем не значит, что молоток гов:%:.

Нужно ли сразу писать куски кода на Ассемблере, если на нём это можно сделать эффективнее?

  • Сразу - нет. Если код выполняется за заданное время и потребляет заданный объём FLASH и RAM, то какая разница как он там внутри устроен?
  • Если код не укладывается в ограничения, то прежде чем его переписывать на ассемблер:
  1. Нужно убедится, что это конечная версия. Вполне возможно, что в процессе разработки этот код может поменяться, причём координальным образом. Не стоит сразу бросаться его переделывать на ассемблер - возможно это всё придётся выбросить (но если вам не жалко своего времени - то пожалуста).
  2. Нужно оценить, насколько он не успевает - если на 10%, то можно переписывать, если на 1000% - то переписывать не стоит, всё равно не получится утоптать в требования. В этом случае нужно координально менять алгоритм или реализацию (например вводить JIT)

 

Share this post


Link to post
Share on other sites
2 hours ago, xvr said:

А о том, нужно ли смотреть листинги после компилятора.

Нет. Не об этом. Я создавал эту тему, и точно знал, что нужно смотреть. Вопрос был в том, кто и как познавал ассемблер.

2 hours ago, xvr said:

Если вы обычный разработчик - нет (даже категорически нет

При этом остаёмся на уровне обычного разработчика навсегда.

Share this post


Link to post
Share on other sites
2 часа назад, haker_fox сказал:

Я создавал эту тему, и точно знал, что нужно смотреть.

А вы можете обосновать, зачем "нужно смотреть"?

Не, я понимаю, если что-то идёт не так, то можно глянуть. Но прям "нужно смотреть" (видимо, после каждой компиляции?) - зачем?

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

1. Когда вношу изменения в код scmRTOS. Ну тут понятно - низкий уровень, нужна максимальная оптимальность, и всё такое.

2. Когда разрабатываю/модифицирую низкоуровневые библиотеки. Тоже понятно. Скажем, работа с GPIO, добавляет ли моя библиотека накладные расходы, и сколько.

3. Когда проект ведёт себя странно/не работает. Полезно глянуть, что вектора прерываний на месте, и всё такое.

А в остальных 90% случаев - я не смотрю в дизассемблер. Потому что я знаю, что компилятор умеет делать свою работу.

Share this post


Link to post
Share on other sites
16 часов назад, AHTOXA сказал:

А в остальных 90% случаев - я не смотрю в дизассемблер. Потому что я знаю, что компилятор умеет делать свою работу.

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

Но я не вижу никаких сложностей в просмотре листинга или дизассемблированного кода. Это как с иностранным языком - одно дело читать, другое писать, а говорить - вообще третье. Команд минимум, ADD, SUB, CMP, MOV, LD, ST и тому подобные понятны интуитивно, порядок операндов и типы адресации один раз в описании системы команд достаточно посмотреть, за подглядывание на незнакомые команды в описание системы команд не бьют.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now