Мелкие задачки для крупных мозгов 11

Тема в разделе "WASM.ZEN", создана пользователем The Svin, 18 мар 2005.

  1. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    Те же но в кепках.

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

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



    Приоритет - скорость.

    Нужно иметь ввиду что во всех до сих пор предъявленных задачках предметная область - передача данных последовательным сигналом. В таких передачах часто полезная передача сменяется состоянием ожидания - т.е. длинными низкими или высокими сигналами. Допустим очень длинная единичная подстрока, затем "всплеск" чередования намного более коротких единичных и нулевых подстрок, затем например длинная нулевая подстрока сменяющаяся долгой единичной подстрокой до следующего "всплеска".
     
  2. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine




    При таких условиях может подойдет принцип такого "предсказывания" (т.к. не известен максимальный размер строки, я выбрал размер DWORD для заполнения длин строк)?
    Код (Text):
    1.         mov     esi,long_binary_string
    2.         mov     edi,memory_pointer
    3.         xor     ecx,ecx
    4.  
    5. align 16  ; цикл всего 2 такта на PIII
    6. @@:     mov     eax,dword [esi]
    7.         add     ecx,32      ; в ecx собираем длину хорошей строки
    8.         add     esi,4
    9.         xor     eax,dword [esi]
    10.         jz      @B
    11.  
    12. ;           хорошая строка закончилась
    13.         sub     ecx,32      ; вычтем упреждение
    14.         mov     dword [edi],ecx ; запишем собранную длину
    15.         sub     esi,4       ;
    16.         add     edi,4       ;
    17.  
    18. ;           теперь считаем любым способом из 10-й задачи
     
  3. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    bogrus

    > "add edi,4 ;теперь считаем любым способом из 10-й задачи"



    Не все так просто:

    add edi,4 нужно делать по условию (ecx > 0) & (eax and 1 = 1), т.е. "хорошая строка" была и закончилась на границе dword'а. Ну примерно так:
    Код (Text):
    1.     sub ecx,32
    2.     mov [edi],ecx
    3.     setnz cl
    4.     and eax,1
    5.     and al,cl
    6.     lea edi,[edi+eax*4]
    7.     sub esi,4
    Хотя если хотя бы два дворда совпали, то и sub ecx и sub esi можно не делать - нужно только как-то учесть особенность первого прохода (т.к. при первом совпадении мы сразу имеем длину строки = 64, а последующее приращение идет по 32).



    Ну и еще вопрос: как из побитового сравнения возвращаться в режим сравнения по dword - сразу после первого прохода или через несколько проходов или анализировать совпадения X >= 32 бит.
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Кстати и первый dword не мешало бы проверить на 0 или -1.

    Может так:
    Код (Text):
    1.     mov esi,long_binary_string
    2.     mov edi,memory_pointer
    3.  
    4.     mov eax,[esi]
    5.     cdq
    6.     sub edx,eax
    7.     jne bybit
    8.  
    9.     xor ecx,ecx
    10. @@: add esi,4
    11.     add ecx,32
    12.     mov edx,[esi]
    13.     cmp edx,eax
    14.     je  @B
    15.  
    16.     mov [edi],ecx
    17.     xor eax,edx
    18.     and eax,1
    19.     lea edi,[edi+eax*4]
    20. bybit:
     
  5. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    Если старший бит текущего двойного слова совпадает с младшим битом следующего слова то битовая строка "продолжается" в следующем я не увидел учёта этого. Решения из 10ой задачи ещё нужно "ассиммилировать" с условиями данной и это кстати одно из алгоритмических "узких горлышек".



    Также переход с "полезного" на "ожидающий" активный и пассивный сигнал может быть в дампе сделан несколько раз а не только в начале.
     
  6. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    The Svin

    > битовая строка "продолжается"..я не увидел учёта этого



    Мое замечание как раз к этому и относилось. В последнем варианте приращение edi делается только в случае несовпадения младшего бита следующего слова с текущим состоянием "ожидающего" сигнала.



    Еще вопрос по 10й задачке: изначально массив длин обнулен или нет ? А то все напрашиваются решения с простым икрементом без предварительного обнуления.
     
  7. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    Его же можно "обнулить" самому если это даст ощутимый эффект.

    Для упрощения задачи можно считать

    1. Дамп большой (т.е. константную фиксированную оптимизацию, вне цикла, - можно игнорировать) Пусть дамп будет от 2^17 до 2^27 бит.

    2. Дамп и выронен битово по 32ум (по двойным словам) и имеет размерность в целом количестве двойных слов.



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



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

    Строб передаваемый сменой единичных - нулевых (размером 4-8 бит допустим 9 изменений) - пауза, единичная в 210-300 бит после строба - начинаю передавать новую информацию, после неё далее чередующиеся "точка - тире" разделенные описанным стробом, на точку 40-50 единиц на тире 70-80.

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

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    leo




    Да, я хотел "пробить" подойдет ли такой принцип, а потом уже можно бы делать обвязку (согласование с 10-й задачей), а то вдруг там километровые строки бит, тогда не грех MMX прикрутить, чтобы "упреждать" не 32 бита, а например сразу 512



    The Svin




    Те циклы что из 10-й? Мне кажется их нереально сделать существенно быстрее
     
  9. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    The Svin



    Лирическое ИМХО:

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

    Приведенный тобой пример это лишний раз подтверждает: длительности точки и тире различаются не менее чем на 20 бит, т.е. на 2-3 байта. А это уже гораздо проще анализировать на компьютере, т.к. с родными единицами - байтами он работает гораздо быстрее, чем с битами. Строб, насколько я понимаю, не несет никакой полезной информации и играет вспомогательную роль - запуск и настройка приема (синхронизация и\или уровень нуля), хотя нельзя исключать вариант, когда строб несет в себе адрес приемника. В любом случае, строб сильно отличается от точек и тире и обнаружить его можно также побайтным, а не побитовым анализом. А посему, если речь идет о "полуизвестном" сигнале с приведенными параметрами, то возможно и считалка длин не нужна. А если хочется уточнить параметры сигнала, то можно это делать и не в реальном времени, сохранив куски дампа выделенные грубым побайтным анализатором.



    Хотя для приведенного примера состояния 0\1 меняются не часто и возможно использование инструкции BSF обеспечит удовлетворительную скорость при подсчете длин с точностью до бита.
     
  10. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    > "с последней хрупкой надеждой смотрят на вас ожидая суперсчиталки длин сигнала"



    Все еще ждем-с ? На "супер" ес-но не тянет, но хоть что-то для затравки:
    Код (Text):
    1.     mov ebp,bitstring_size
    2.     mov esi,bitstring_ptr
    3.     mov edi,destarray_ptr
    4.     add ebp,esi
    5.  
    6.     xor ecx,ecx
    7.     mov eax,[esi]      ;первый дворд сигнала
    8.         mov [edi],ecx      ;обнуляем первую длину
    9.     cdq                ;edx = старшему биту eax
    10.     cmp edx,eax        ;контроль наличия переходов 0\1
    11.     jne scan
    12.        
    13. dloop:  ;подсчитываем дворды
    14.     add esi,4
    15.       cmp esi,ebp
    16.       jae exit
    17.     add ecx,32
    18.     mov eax,[esi]
    19.     cmp eax,edx
    20.     je  dloop
    21.  
    22.     mov [edi],ecx       ;сохраняем длину
    23.     xor ecx,ecx
    24.     mov [edi+4],ecx     ;обнуляем следующую длину
    25.     xor edx,eax         ;проверяем продолжение подстроки
    26.     and edx,1
    27.     lea edi,[edi+edx*4] ;если нет продолжения, то инкремент edi
    28.  
    29. scan:   ;выделяем переходы
    30.     xor ebx,ebx         ;позиция предыдущего перехода
    31.     mov edx,eax
    32.     add edx,edx
    33.     xor edx,eax
    34.     and edx,-2
    35.     jz  skip            ;нет переходов
    36.  
    37.     ;сканируем переходы
    38.     bsf ecx,edx
    39. bsloop:  
    40.     sub ebx,ecx         ;длина подстроки с обр.знаком
    41.     btr edx,ecx
    42.     sub [edi],ebx
    43.     mov ebx,ecx
    44.     add edi,4
    45.     mov [edi],0         ;обнуляем следующую длину
    46.     bsf ecx,edx
    47.     jnz bsloop
    48.  
    49. skip:   ;запись длины последней подстроки
    50.     sub ebx,32
    51.     sub [edi],ebx
    52.     xor ecx,ecx
    53.     mov [edi+4],ecx     ;обнуляем следующую длину
    54.  
    55.     ;следующий dword
    56.     add esi,4
    57.       cmp esi,ebp
    58.       jae exit
    59.     cdq                 ;сохраняем старший бит пред.слова в edx
    60.     mov eax,[esi]
    61.     xor edx,eax         ;контроль продолжения строки
    62.     and edx,1
    63.     lea edi,[edi+4*edx]
    64.  
    65.     ;проверка наличия переходов
    66.     ;(возможны другие варианты, например просто jmp scan )
    67.     cdq
    68.     cmp edx,eax
    69.     jne scan  
    70.     jmp dloop  
    71.  
    72. exit:   ;конец строки - подсчитываем размер массива длин
    73.     mov eax,edi
    74.     sub eax,destarray_ptr
    75.     shr eax,2
    76.     cmp [edi],1
    77.     sbb eax,0
    78.     ;в eax - длина число элементов массива длин