· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ZEN —› a^=b^=a^=b; //обмен значений

<< . 1 . 2 . 3 .

Посл.отвђт Сообщенiе


Дата: Июн 29, 2003 16:33:44 · Поправил: Black_mirror

Quantum

Ты был прав, без цикла получается быстрее, только вот не понятно на сколько. Оба варианта написал на асме и вставил в код, замеряющий время(а не сделал их ввиде функций). Код для замера времени сказал что он выполнится за 11 тактов(rdtsc/mov ebx,eax/.../rdtsc). Этот код был заключен в цикл, который выполнял замер 65536 раз, и сохранял минимальный результат. Вариант без цикла(для подсчета бит) работал 51 такт, с циклом - 107. Проверял на eax=0ffffffffh. Затем выровнял метку для организации внешнего цикла, и метку во втором варианте. Первый вариант стал работать за 14(!!) тактов, а второй за 90.
Вообщем я не понимаю прочему такая большая разница: 51 и 14 тактов ... Вернее не понимаю почему такая большая разника для кода в котором вообще нет переходов?!


Дата: Июл 1, 2003 09:39:13

>... почему такая большая разника для кода в
> котором вообще нет переходов?!

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

1) Он неправильно предсказывает переход;
2) Всегда лучше, когда условный переход редко выполняется, вот у Зубкова есть такой пример:

; Процедура rand
; возвращает в ЕАХ случайное положительное 32-; битное число
; (от 0 до 231-2)
;
rand proc near
push edx
; считать последнее случайное число
mov eax,dword ptr seed
; проверить его, если это -1,
test eax,eax
; функция еще ни разу не
js fetch_seed
; вызывалась и надо создать
; начальное значение
randomize:
; умножить на число а,
mul dword ptr rand_a
; взять остаток от
; деления на 231-1
div dword ptr rand_m
mov eax,edx
; сохранить для
; следующих вызовов
mov dword ptr seed,eax
pop edx
ret

fetch_seed:
push ds
push 0040h
pop ds
mov eax,dword ptr ds:006Ch
; считать
; двойное слово из области
pop ds
; данных BIOS по адресу
; 0040:0060 - текущее число
jmp short randomize
; тактов таймера

Видимо, дело в этом ?


Дата: Янв 2, 2004 05:10:43

Black_mirror
А вот код для проверки попадает беззнаковое число в один из не пересекающихся интервалов [min1,max1), [min2,max2)
Суперский пример! Оказывается, что интервалов может быть не только 2. Вот, кстати, немного изменённый пример для определения принадлежности байта к печатным цифрам и буквам (вроде IsAlphaNumeric(char x)):
    cmp al,'0'
    sbb ah,ah
    cmp al,'9' + 1
    adc ah,0
    cmp al,'A'
    sbb ah,0
    cmp al,'Z' + 1
    adc ah,0
    cmp al,'a'
    sbb ah,0
    cmp al,'z' + 1
    adc ah,0


Дата: Янв 2, 2004 05:22:34 · Поправил: Quantum

Или ещё лучше! Для любого количества интервалов:
; ============================================
; Params:
;  AL - входной байт
; Return:
;  Z  - флаг снят, если AL принадлежит к
;       одному из непересекающихся интервалов
; --------------------------------------------
multiint PROC SYSCALL uses esi
    xchg al,dl
    xor dh,dh
    mov ecx,INTS_LEN
    mov esi,OFFSET @ints
    cld
@@: lodsw
    cmp dl,al
    sbb dh,0
    cmp dl,ah
    adc dh,0
    loop @B
    ret
@ints db '0','9' + 1 ; интервал 1 -> ['0', '9']
      db 'A','Z' + 1 ; интервал 2 -> ['A', 'Z']
      db 'a','z' + 1 ; интервал 3 -> ['a', 'z']
      db '+','+' + 1 ; интервал 4 -> {'+'}
      db '-','-' + 1 ; интервал 5 -> {'-'}
      ; и т.д.
INTS_LEN  EQU ($ - @ints) / 2
multiint ENDP


Дата: Янв 2, 2004 07:03:56

Quantum
Твой код агрессивно пишет в партиальные регистры и поэтому страдает серьезной деградацией перфоманциi :)


Дата: Янв 2, 2004 07:44:49

captain cobalt
Разве сложно переделать под 32х-битные регистры? Можно даже не использовать LODSx, которая отрицательно сказывается на производительности. Зато в предоставленном виде код более читабельный.


Дата: Янв 2, 2004 08:19:01

Хм... Ну... Если просят код дзена, то наверное имеет смысл СНАЧАЛА обработать напильником, а потом показывать народу. Смотри, другие клочки кода в этом треде отнюдь не являются самодокументированными...

А код действительно работает... :)
Только, возможно, следует читать: "флаг Z установлен если НЕ принадлежит"


Дата: Янв 2, 2004 14:19:28 · Поправил: S_T_A_S_

Еще один вариант
интервалы '0' - '9' и 'A' - 'F'
mov CL, value
sub CL, '0'-1
;-----------0123456789:;<=>?@ABCDEFGHIJKLMNO
mov EAX, 11111111110000000111111000000000y
shl EAX, CL
jc  hex


Дата: Янв 2, 2004 21:39:11

Ещё вариант для случая, когда диапазон большой и интервалов много:

В отсортированном по возрастанию массиве границ интервалов находится количество элементов меньше проверяемого. Проверяемый элемент попадает в интервал если это количество нечетное.

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

В общем, что-то вроде этого:
; на входе: eax - проверяемое значение
; на выходе: carry flag - входит или нет, ebx - номер интервала
findint:
 xor ebx,ebx
.search:
 cmp eax,[ints+ebx]
 jae .found
 inc ebx
 cmp ebx,ints.len
 jb  .search
.found:
 shr ebx,1 
 ret
ints dd '0','9'+1,'A','F'+1,'a','f'+1
.len equ $-ints
Набрано прямо здесь, проверять или оптимизировать лень. ;)


Дата: Янв 2, 2004 21:54:16

captain cobalt
Если просят код дзена, то наверное имеет смысл СНАЧАЛА обработать напильником, а потом показывать народу.
А оптимизация по размеру разве дзеном не является? Почему ты решил, что я не обработал этот код предварительно напильником? И вообще, данный код основан на примере by Black_mirror, так что совсем моим я его назвать не могу.

Только, возможно, следует читать: "флаг Z установлен если НЕ принадлежит"
Исправил.

S_T_A_S_
bsl_zcs
Записываю! :-)


Дата: Янв 2, 2004 23:18:19

Quantum
Лучше отсюда


Дата: Янв 3, 2004 00:24:06

bsl_zcs
> Ещё вариант для случая, когда диапазон большой и интервалов много

а на этот случай есть структуры данных под названием
деревья промежутков (interval tree)


Дата: Янв 3, 2004 03:06:04

S_T_A_S_
Спасибо за ссылку!

captain cobalt
Если интервалы отсортированы и использовать бинарный поиск, то вариант bsl_zcs будет не хуже поиска по дереву. Принцип в обоих случаях тотже.

<< . 1 . 2 . 3 .


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.087