Текущий архив: 2004.10.24;
Скачать: CL | DM;
ВнизПоиск в бинарном файле Найти похожие ветки
← →
GuAV © (2004-10-07 02:05) [240][239] опять не рабочий код дал, блин... вот рабочий:
@@CompareWholeString:
Test EBx, EBx
Jz @@Constant_Exists
Cmp EDx, EBx
Jna @@Exit_False
MOV ECX, EBX
@@CWs_1:
Test ECx, 1
Jz @@CWs_2
Sub ECx, 1
MOV AL, [ESi+ECx]
CMP AL, [EDi+ECx]
JNE @@SkipBTest
@@CWs_2:
Test ECx, 2
Jz @@CWs_4
Sub ECx, 2
MOV AX, [ESi+ECx]
CMP AX, [EDi+ECx]
JNE @@SkipBTest
@@CWs_4:
Test ECx, 4
Jz @@CWs_8
Sub ECx, 4
MOV EAX, [ESi+ECx]
CMP EAX, [EDi+ECx]
JNE @@SkipBTest
@@CWs_8:
@@CW_Loop:
SUB ECX, 8
JL @@Constant_Exists
MovQ MM3, [ESi+ECx]
MovQ MM2, [EDi+ECx]
PCMPEQB MM3, MM2
PACKSSWB MM3, MM3
MovD EAX, MM3
Cmp EAX, -1
JE @@CW_Loop
@@SkipBTest:
Mov ECx, EDx
Cmp EDx,4
Jg @@Scan
Jmp @@LastDWord
@@Constant_Exists:
Pop EAx
Sub EAx, EDx
← →
GuAV © (2004-10-07 02:23) [241]
@@CompareWholeString:
Test EBx, EBx
Jz @@Constant_Exists
Cmp EDx, EBx
Jna @@Exit_False
Push ESi
Push EDi
Add EDi, EBx
Add ESi, EBx
@@CWs_1:
Test EBx, 1
Jz @@CWs_2
Sub ESi, 1
Sub EDi, 1
MOV AL, [ESi]
CMP AL, [EDi]
JNE @@SkipBTest1
@@CWs_2:
Test EBx, 2
Jz @@CWs_4
Sub ESi, 2
Sub EDi, 2
MOV AX, [ESi]
CMP AX, [EDi]
JNE @@SkipBTest1
@@CWs_4:
Test EBx, 4
Jz @@CWs_8
Sub ESi, 4
Sub EDi, 4
MOV EAX, [ESi]
CMP EAX, [EDi]
JNE @@SkipBTest1
@@CWs_8:
MOV ECX, EBX
@@CW_Loop:
SUB ECX, 8
JL @@Constant_Exists1
SUB ESi, 8
SUB EDi, 8
MovQ MM3, [ESi]
MovQ MM2, [EDi]
PCMPEQB MM3, MM2
PACKSSWB MM3, MM3
MovD EAX, MM3
Cmp EAX, -1
JE @@CW_Loop
@@SkipBTest:
Mov ECx, EDx
@@SkipBTest1:
Cmp EDx,4
Pop EDi
Pop ESi
Jg @@Scan
Jmp @@LastDWord
@@Constant_Exists1:
Pop EDi
Pop ESi
@@Constant_Exists:
Pop EAx
Sub EAx, EDx
← →
GuAV © (2004-10-07 16:10) [242]По поводу поиска по восем байт без AV мысль такая.
сначала Test Buffer, 7 и если не нуль то
{
читать в mmreg 8 байт из [Buffer and (not 7)]
в начало могут попасть байты из длины и счета ссылок, чтобы их проигнорировать, тестить результатPCMPEQB / PACKUSWB
вот такой маской (адресовать в самой маске по [Buffer and 7)])SmallTestArray: array[0..7] of LongWord =
поправить буфер Buffer:=Buffer and (not 7)
($00000000,
$F0000000,
$FF000000,
$FFF00000,
$FFFF0000,
$FFFFF000,
$FFFFFF00,
$FFFFFFF0);
}
потом читать по 8 байт из буфера (он уже QWord aligned)
потом читать остаток, если он есть. Причём 8 байт, хотя осталось меньше. Тестить масокй из аналогичного массива. Буфер остался QWord Aligned, поэтому чтение не пересечет 4к-границу, т.е. AV не будет.
← →
Defunct © (2004-10-07 19:33) [243]2 GuruAV: я смотрю вы из Харькова, не хотите быть соавтором статьи в ВАКовском журнале "Проблемы программирования"? Если да, тогда давайте пересечемся в аське.
← →
GuAV © (2004-10-07 20:11) [244]Реализация [242] для поиска из [193]
@@WideScan:
Cmp ECx, 16
Jb @@SmallScan
Mov Al,[EAx]
Mov Ah, Al
MovD MM6, EAx
PUNPCKLWD MM6, MM6
PUNPCKLDQ MM6, MM6
Push ECx
Test EDx, 7
Jz @@Scan5
Mov ECx, EDx
And ECx, 7
And EDx, not 7
MovQ MM7, [EDx]
PCMPEQB MM7, MM6
PACKSSWB MM7, MM7
MovD EAx, MM7
And EAx, SmallTestArray[ECx*4].DWord
Jnz @@1stbytes
Mov EAx, ECx
Mov ECx, [ESp]
Add EDx, 8
Sub ECx, EAx
@@Scan5:
MovQ MM7, [EDx]
PCMPEQB MM7, MM6
PACKSSWB MM7, MM7
MovD EAx, MM7
Test EAx, EAx
Jnz @@CharFound2
Add EDx,8
Sub ECx,8
Jg @@Scan5
@@Exit_False2:
Emms
Pop EAx
Xor EAx, EAx
Ret
@@1stbytes:
Mov [ESp], ECx
Mov ECx, 8
@@CharFound2:
Dec Ecx
Test EAx,0Fh
Jnz @@Check2
Shr EAx,4
Jmp @@CharFound2
@@Loop2:
Dec Ecx
Test Al,Al
Js @@Check2
Shr EAx,8
Jmp @@Loop2
@@Check2:
Test ECx,ECx
Js @@Exit_False2
Emms
Pop EAx
Sub EAx, ECx
Ret
> пересечемся в аське
никак. только мыло.
← →
Defunct © (2004-10-08 20:21) [245]> никак. только мыло.
чего так? религия запрещает? как насчет MSN
← →
GuAV © (2004-10-08 23:16) [246]<off>
> чего так? религия запрещает? как насчет MSN
То запрещает, что у меня так:
соединился, проверил почту, скачал интересные ветки, отключился.
написал ответы, соединился, отправил всё, отключился.
Ибо время-деньги. Это называется диал-ап.
Кстати, что я могу написать про "Проблемы программирования", если я не программист ?
</off>
← →
Defunct © (2004-10-09 00:19) [247]> Ибо время-деньги. Это называется диал-ап.
думаю 30 мин нам хватит. а там уже можно и почтой.
> Кстати, что я могу написать про "Проблемы программирования", если я не программист ?
Писать надо не про проблемы программирования, а про ускорение поиска подстроки в строке. "Проблемы программирования" - это просто название журнала.
ВАК = Высшая Аттестационная Комиссия.
Судя по анкете вы еще учитесь, научная статья вам повредит? Материала в этой ветке уже предостаточно для хорошей статьи.
PS: завтра попробую [244] и займусь реализацией [238].
← →
GuAV © (2004-10-09 00:28) [248]Defunct © (09.10.04 00:19) [247]
Ок. завтра во второй половине дня или послезавтра пересечёмся.
Хотя имхо если по этой ветке, то надо сначало довести начатое дело.
Да. Я действительно ещё учусь.
← →
GuAV © (2004-10-09 00:29) [249]
> завтра
то есть не завтра, а в субботу, т.е. сегодня уже. на время не глянул.
← →
GuAV © (2004-10-09 15:49) [250]Мой ICQ в анкете...
← →
Defunct © (2004-10-09 16:57) [251][244]
WideScan - поиск символа, и он используется только при длинне подстроки = 1 (подстрока состоит из одного символа). Первый найденный символ и будет результатом. Менять с учетом [238] надо было WideSearch, именно в нем надо просматривать сразу все возможные вхождения первого символа нарушения QWord Align.
← →
GuAV © (2004-10-10 14:30) [252]Для коротких строк в [193] после проверки возврат на цикл уже длиных строк, это иожет привести к потере быстродействия и явно создаёт проблемы для дальнейшей оптимизации. предлагаю вынести __WideScan; и __WideString; и разделить CompareWholeString для них.
procedure __WideScan;
asm
Mov Al,[EAx]
Mov Ah, Al
MovD MM6, EAx
PUNPCKLWD MM6, MM6
PUNPCKLDQ MM6, MM6
Push ECx
Test EDx, 7
Jz @@Scan5
Mov ECx, EDx
And ECx, 7
And EDx, not 7
MovQ MM7, [EDx]
PCMPEQB MM7, MM6
PACKSSWB MM7, MM7
MovD EAx, MM7
And EAx, SmallTestArray[ECx*4].DWord
Jnz @@1stbytes
Mov EAx, ECx
Mov ECx, [ESp]
Add EDx, 8
Sub ECx, EAx
@@Scan5:
MovQ MM7, [EDx]
PCMPEQB MM7, MM6
PACKSSWB MM7, MM7
MovD EAx, MM7
Test EAx, EAx
Jnz @@CharFound2
Add EDx,8
Sub ECx,8
Jg @@Scan5
@@Exit_False2:
Emms
Pop EAx
Xor EAx, EAx
Ret
@@1stbytes:
Mov [ESp], ECx
Mov ECx, 8
Jmp @@CharFound2
@@CharFound21:
Shr EAx,4
@@CharFound2:
Dec Ecx
Test EAx,0Fh
Jz @@CharFound21
@@Check2:
Test ECx,ECx
Js @@Exit_False2
Emms
Pop EAx
Sub EAx, ECx
end;
procedure __WideString;
asm
MovD MM4, EAx
Mov Ah, Al
MovD MM6, EAx
PUNPCKLWD MM6, MM6
PUNPCKLDQ MM6, MM6
@@Scan:
MovQ MM7, [Edi]
PCMPEQB MM7, MM6
PACKSSWB MM7, MM7
MovD EAx, MM7
Test EAx, EAx
Jnz @@CharFound
Add EDi, 8
Mov EAx, Edi
And EAx, 7
Sub EDi, EAx // Aligning index
Sub ECx, 8
Add ECx, EAx
@@Scan2:
MovQ MM7, [Edi]
PCMPEQB MM7, MM6
PACKSSWB MM7,MM7
MovD EAx, MM7
Test EAx, EAx
Jnz @@CharFound
Add EDi,8
Sub ECx,8
Jg @@Scan
Jmp @@Exit_False
@@CharFound:
MovQ MM7, [Edi]
PCMPEQB MM7, MM6
MovD EAx, MM7
Test EAx, EAx
Jnz @@Loop1
Add EDi,4
Sub ECx,4
PSRLQ MM7,32
MovD EAx, MM7
@@Loop1:
inc EDi
dec Ecx
Test Al,Al
Js @@Check
Shr EAx,8
Jmp @@Loop1
@@Check:
MovD EAx, MM4
@@CheckLastChar: // as proposed in Boyer-Mur alhorithm
Mov EDx, ECx // store new residual buffer size
Test EDx, EDx
Js @@Exit_False
Test EBx, EBx
Js @@Constant_Exists
Cmp Ah, [EBx+Edi]
Jz @@CompareWholeString
Test EDx, EDx
Jg @@Scan
@@Exit_False:
Pop EAx
Xor EAx,EAx
Jmp @@Leave_Proc
@@NotFound_Exit:
Xor EAx, EAx
Ret
@@CompareWholeString:
Test EBx, EBx
Jz @@Constant_Exists
Cmp EDx, EBx
Jna @@Exit_False
MOV ECX, EBX
@@CWs_1:
Test ECx, 1
Jz @@CWs_2
Sub ECx, 1
MOV AL, [ESi+ECx]
CMP AL, [EDi+ECx]
JNE @@SkipBTest
@@CWs_2:
Test ECx, 2
Jz @@CWs_4
Sub ECx, 2
MOV AX, [ESi+ECx]
CMP AX, [EDi+ECx]
JNE @@SkipBTest
@@CWs_4:
Test ECx, 4
Jz @@CWs_8
Sub ECx, 4
MOV EAX, [ESi+ECx]
CMP EAX, [EDi+ECx]
JNE @@SkipBTest
@@CWs_8:
@@CW_Loop:
SUB ECX, 8
JL @@Constant_Exists
MovQ MM3, [ESi+ECx]
MovQ MM2, [EDi+ECx]
PCMPEQB MM3, MM2
PACKSSWB MM3, MM3
MovD EAX, MM3
Cmp EAX, -1
JE @@CW_Loop
@@SkipBTest:
Mov ECx, EDx
@@SkipBTest1:
Test EDx, EDx
Jg @@Scan
Jmp @@Exit_False
@@Constant_Exists:
Pop EAx
Sub EAx, EDx
@@Leave_Proc:
EMMS
Pop EBp
Pop EBx
Pop ESi
Pop EDi
End;
// продолжение следующим постом
← →
GuAV © (2004-10-10 14:32) [253]
Function PosDefunct_a(const Constant, Buffer: string): Integer; Assembler;
Asm
Test eax, eax
Jz @@NotFound_Exit
Test edx, edx
Jz @@NotFound_Exit
Mov ECx, [EDx-4]
Test ECx, ECx
Jz @@NotFound_Exit
Cmp [EAx-4],1
Jnz @@WideSearch
Cmp ECx, 8
Ja @@SmallScan
// CharPos
@@Scan4:
Mov Ch,[EAx]
// Ch - char
// EDx - pointer to buffer
// cl - length
@@CharPos:
Mov EAx,[EDx]
Cmp Ch,Al
Jz @Found1
cmp Ch,Ah
Jz @Found2
Shr EAx,16
Cmp Ch,Al
Jz @Found3
Cmp Ch,Ah
Jz @Found4
Cmp Cl,4
Jna @NotFound
Mov EAx,[EDx+4]
Cmp Ch, Al
Jz @Found5
Cmp Ch, Ah
Jz @Found6
Shr EAx, 16
Cmp Ch, Al
Jz @Found7
Cmp Ch, Ah
Jz @Found8
@NotFound:
XOr EAx, EAx
Ret
@Found1:
Mov EAx,1
Jmp @Validation
@Found2:
Mov EAx,2
Jmp @Validation
@Found3:
Mov EAx,3
Jmp @Validation
@Found4:
Mov EAx,4
Jmp @Validation
@Found5:
Mov EAx,5
Jmp @Validation
@Found6:
Mov EAx,6
Jmp @Validation
@Found7:
Mov EAx,7
Jmp @Validation
@Found8:
Mov EAx,8
Jmp @Validation
@Validation:
Cmp Al,Cl
Ja @NotFound
ret
nop
nop // alignment for better performance
@@SmallScan:
Cmp ECx, 16
Ja __WideScan
Push ECx
Mov Ch,[EAx]
@@Scan8:
Push ECx
Call @@CharPos
Pop ECx
Test EAx, EAx
Jz @Validation3
Sub Cl, Al
Pop EAx
Sub Al, Cl
Ret
@Validation3:
Sub Cl, 8
Add EDx, 8
Cmp Cl, 0
Jg @@Scan8
Add ESP, 4
Ret
/////////////////////////////////////////////
@Small_String:
Cmp ECx, [EAx-4]
Jb @NotFound
Mov Ch, [EAx]
Push ECx
Push EBx
Push ESi
Mov ESi, EAx
Mov EBx,[ESi-4]
Dec EBx
@Scan6:
Push ECx
@Scan7:
Call @@CharPos
Pop ECx
Test EAx, EAx
Jz @Validation2
Sub Cl, Al
Add EDx, EAx
Cmp Cl, Bl
Jb @NotFound2
Push ECx
Mov ECx, EBx
@Loop2:
Mov Al, [ESi+ECx]
Cmp Al, [EDx+ECx-1]
Jnz @Scan7
Loop @Loop2
Pop ECx
Mov Ah, 0
Pop ESi
Pop EBx
Pop EAx
Sub EAx, ECx
ret
@Validation2:
Sub Cl, 8
Add EDx, 8
Cmp Cl, 0
Jg @Scan6
@NotFound2:
Pop ESi
Pop EBx
Add ESp, 4
Xor EAx, EAx
Ret
@@WideSearch:
Cmp ECx,32
Jb @Small_String
Push EDi
Push ESi
Push EBx
Push EBp
MOV ESI, EAX
Mov EDi, EDx
Push ECx
Mov EBX, [ESI-4]
Test EBx, EBx
Jz @@Exit_False
Mov Al, [ESi]
Cmp EBx, ECx
Ja @@Exit_False
Jnz @@Normal_Work
Cmp AL, [Edi]
Jnz @@Exit_False
@@Normal_Work:
Dec EBX
Mov Ah, [ESi+EBx]
Dec EBx
Mov EDx,ECx
Inc ESi
Mov EBp, ESi
Cmp ECx, 8
Ja __WideString
@@Scan3:
Push EAx
Mov Ch, Al
Mov EDx, EDi
Call @@CharPos
Mov Ch, 0
Sub ECx, EAx
Add EDi, EAx
Pop EDx
Test EAx,EAx
Jz @@Exit_False
Xchg EAx, EDx
// Jmp @@CheckLastChar
//@@CheckLastChar: // as proposed in Boyer-Mur alhorithm
Mov EDx, ECx // store new residual buffer size
Test EDx, EDx
Js @@Exit_False
Test EBx, EBx
Js @@Constant_Exists
Cmp Ah, [EBx+Edi]
Jz @@CompareWholeString
Test EDx, EDx
Jg @@Scan3
@@Exit_False:
Pop EAx
Xor EAx,EAx
Jmp @@Leave_Proc
@@NotFound_Exit:
Xor EAx, EAx
Ret
@@CompareWholeString:
Test EBx, EBx
Jz @@Constant_Exists
Cmp EDx, EBx
Jna @@Exit_False
MOV ECX, EBX
@@CW_Loop:
SUB ECX, 4
JL @@CW_Last123bytes
MOV EAX, [ESi+ECx]
JZ @@CW_LastDWord
CMP EAX, [EDi+ECx]
JE @@CW_Loop
Mov ECx, EDx
JMP @@SkipBTest1
@@CW_LastDWord:
CMP EAX, [EDi]
JE @@Constant_Exists
Mov ECx, EDx
JMP @@SkipBTest1
@@CW_Last123bytes:
ADD ECX, 2
JS @@Last1
@@Last3:
MOV AX, [ESi]
JZ @@Last2
CMP AX, [EDi]
JNE @@SkipBTest
MOV AL, [ESi+2]
CMP AL, [EDi+2]
JE @@Constant_Exists
Mov ECx, EDx
JMP @@SkipBTest1
@@Last2:
CMP AX, [EDi]
JE @@Constant_Exists
Mov ECx, EDx
JMP @@SkipBTest1
@@Last1:
MOV AL, [ESi]
CMP AL, [EDi]
JE @@Constant_Exists
@@SkipBTest:
Mov ECx, EDx
@@SkipBTest1:
Test EDx, EDx
Jg @@Scan3
Jmp @@Exit_False
@@Constant_Exists:
Pop EAx
Sub EAx, EDx
@@Leave_Proc:
Pop EBp
Pop EBx
Pop ESi
Pop EDi
End;
← →
GuAV © (2004-10-10 15:05) [254]Моя версия SmallScan:
@@SmallScan:
Cmp ECx, 16
Ja __WideScan
Mov Ch,[EAx]
Push ECx
Call @@CharPos
Pop ECx
Test EAx, EAx
Jnz @@SmallDone
Add EDx, 8
Sub ECx, 8
Call @@CharPos
Test EAx, EAx
Jz @@SmallDone
Add EAx, 8
@@SmallDone:
Ret
← →
Sha © (2004-10-11 12:58) [255]> Defunct
> GuAV
Скорость - это хорошо.
Но хочется все-таки увидеть функцию, прошедшую тест Validate0.
← →
Defunct © (2004-10-11 17:00) [256]> Но хочется все-таки увидеть функцию, прошедшую тест Validate0.
Работаем над этим, попутно делаем описание.
К концу недели должна быть функция прошедшая validate0 и без потерь в скорости.
← →
Sha © (2004-10-11 21:35) [257]Defunct © (11.10.04 17:00) [256]
OK.
Попробую пока переделать свою с Pascal на Asm.
Потом сравним ;)
← →
GuAV © (2004-10-12 00:46) [258]
> маленькой хитрости - изменения направления сравнения.
Почему это усокряет функцию ?
← →
Defunct © (2004-10-12 01:06) [259]>> маленькой хитрости - изменения направления сравнения.
> Почему это усокряет функцию ?
Я вам пытался об этом сказать, но вы не хотели слушать мотивируя примером с наперсточником, пятью наперстками и шариком. ;)
У вас в аське есть ответ на этот вопрос.
Помните, что главной задачей является поиск несовпадения, а не наоборот. Чем быстрее отбракуем строку, тем быстрее продолжим линейный поиск символа.
Вот строки для сравнения, какой способ определит несовпадение быстрее всего? С конца, с начала, или в двух направлениях, или в четырех?
[xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]
[xxbxxxxxxxxxxxxxxxxxxxxxxxxxxxx]
[xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]
[xxxxxxxxxxxxxxxxxxxxxxxxxxxxcxx]
[xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]
[xxxxxxxxxxxxxcxxxxxxxxxxxxxxxxx]
← →
GuAV © (2004-10-12 01:51) [260]
//Нет не в том дело.
//попробуйте такое:
const Len = 1024*256;
var TestArray: array[0..Len] of Byte;
procedure P1;
asm
MOV ECX, Len
@@1:
MOV AL, TestArray[ECX].Byte
DEC ECX
CMP ECX, 0
JNZ @@1
end;
procedure P2;
asm
MOV ECX, 0
@@1:
MOV AL, TestArray[ECX].Byte
INC ECX
CMP ECX, Len
JNZ @@1
end;
procedure TForm1.Button1Click(Sender: TObject);
var I, T1, T2: Integer;
begin
T1:=GetTickCount;
for I:=1 to 1000 do
P1;
T1:=GetTickCount-T1;
T2:=GetTickCount;
for I:=1 to 1000 do
P2;
T2:=GetTickCount-T2;
Memo1.Lines.Add("P1="+IntToStr(T1));
Memo1.Lines.Add("P2="+IntToStr(T2));
end;
procedure TForm1.Button2Click(Sender: TObject);
var I, T1, T2: Integer;
begin
T2:=GetTickCount;
for I:=1 to 1000 do
P2;
T2:=GetTickCount-T2;
T1:=GetTickCount;
for I:=1 to 1000 do
P1;
T1:=GetTickCount-T1;
Memo1.Lines.Add("P1="+IntToStr(T1));
Memo1.Lines.Add("P2="+IntToStr(T2));
end;
ps на [258] хотел получить ответ Sha ©
← →
Defunct © (2004-10-12 01:58) [261][260]
ну и?
на P4 одинаково.
← →
GuAV © (2004-10-12 02:05) [262]У меня нет. Но я понял уже почему нет (разное кодирование CMP). Таки наверное Вы правы. Не буду больше сбивать Вас с верного пути...
← →
GuAV © (2004-10-12 11:26) [263]Думал над идеей Defunct, обратном порядке и напрестке.
Вывод. Поскольку обратный порядок существенно быстрее чем прямой, данный тест необъективен.
Объективный тест:
Строка случайной длины.
Берется случайная подстрока из этой строки (с приоритетом в сторону коротких строк).
Иногда в ней делаются различия случайные (с приоритетом в сторону неболшого числа различий).
← →
GuAV © (2004-10-12 11:33) [264]Естественно всем тогда одинаковый RandSeed
Страницы: 1 2 3 4 5 6 7 вся ветка
Текущий архив: 2004.10.24;
Скачать: CL | DM;
Память: 1.07 MB
Время: 0.065 c