![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
XOR для массива
MikeZ © (2006-06-04 16:30:00)Всем день добрый!
Надо сделать XOR для чисел, являющихся элементами массива.
Сейчас делаю a[i] xor b[i], перебирая так весь массив.
Есть ли какой-нибудь способ делать это по-красивее и, главное, побыстрее.
tesseract (2006-06-08 13:22:00) [1]
> Sapersky (08.06.06 13:12) [65]
при страте программы можно узнать тип процессора и вызывать функции напрямую.
Sapersky (2006-06-08 13:12:00) [2]Но всеже ошибочка ;-)
Да, точно. Спасибо за исправление.
http://www.fastcode.sourceforge.net
В RTL D2006 включили некоторые функции оттуда.
Только вот такой момент - на процессорах, которые в fastcode не тестируют (например P3), результаты часто получаются прямо противоположные. И без того неторопливые "старички" тормозят ещё сильнее :(
tesseract (2006-06-08 11:00:00) [3]http://www.fastcode.sourceforge.net - интересная штучка кстати, обещают кое-где 3-х кратный прирост скорости.
Pavia (2006-06-07 19:34:00) [4]Sapersky
С MMX и SSE я пока не работал.
Но всеже ошибочка ;-)
@bytes:
mov al, [edi]
xor [esi], al
inc edi
inc esi
dec ecx
jnz @bytes
Sapersky (2006-06-07 17:12:00) [5]Вот с MMX.
В 2 с лишним раза быстрее варианта Pavia (в 1.5 - если сделать там аналогичную развёртку цикла), но:
- результат будет в Src1, а не в отдельном массиве - писал по аналогии с [7], сейчас лень переделывать.
- адреса массивов должны быть выравнены на 8 (т.е. кратны 8). Нужно либо выравнивать вручную (Delphi выравнивает на 4), либо выделять память чем-нибудь вроде VirtualAlloc, который, если не ошибаюсь, выравнивает на 64k. Я для тестирования использовал битмапы, они тоже хорошо выравниваются.
- тестировал на Cel2.8, выяснилось, что имеет преимущество только с небольшими объёмами данных (которые помещаются в кэш), иначе ограничивает относительно медленная шина памяти.
procedure Mem_XorMMX(Src1, Src2: Pointer; Count: Integer);
// EAX = Src1, EDX = Src2, ECX = Count
asm
push esi
push edi
mov esi, eax // Src1 to esi
mov edi, edx // Src2 to edi
mov edx, ecx // copy Count to edx
shr ecx,5
jz @bytestart
@quads:
db $0F,$6F,$06 /// movq mm0,[esi]
db $0F,$6F,$4E,$08 /// movq mm1,[esi+8]
db $0F,$6F,$56,$10 /// movq mm2,[esi+16]
db $0F,$6F,$5E,$18 /// movq mm3,[esi+24]
db $0F,$EF,$07 /// pxor mm0, [edi]
db $0F,$EF,$4F,$08 /// pxor mm1, [edi+8]
db $0F,$EF,$57,$10 /// pxor mm2, [edi+16]
db $0F,$EF,$5F,$18 /// pxor mm3, [edi+24]
db $0F,$7F,$06 /// movq [esi], mm0
db $0F,$7F,$4E,$08 /// movq [esi+8], mm1
db $0F,$7F,$56,$10 /// movq [esi+16], mm2
db $0F,$7F,$5E,$18 /// movq [esi+24], mm3
add edi,32
add esi,32
dec ecx
jnz @quads
db $0F,$77 // emms
@bytestart:
mov ecx, edx
and ecx, 31 // cutting all >= 32
jz @exit
@bytes:
mov eax, [edi]
xor [esi], eax
inc edi
inc esi
dec ecx
jnz @bytes
@exit:
pop edi
pop esi
end;
Теория, если интересно:
http://www.tommesani.com/Docs.html
MikeZ (2006-06-07 14:11:00) [6]В принципе - именно байт. Так что посмотрю.
tesseract (2006-06-07 13:26:00) [7]
> а какой-нибудь алгоритм, работающий быстрее моего. Как
> именно работающий - неважно.
Если массив имеено байт то код pavia должен быть в 4 раза быстрее.
MikeZ (2006-06-07 13:18:00) [8]Так, прошу всех не драться :-)
Таки да, виноват я, некорректно сформулровал вопрос - спешил...
Дано: есть три одинаковых массива (A,B,C), тип эл-та - integer.
Надо: i-му эл-ту 3-го массива (C) присвоить значение C[i] := A[i] XOR B[i].
Я это делал в цикле, проходя по всем эл-там массива. И хотелось узнать, можно ли делать XOR для массива целиком, а не по-элементно. Под словом "целиком" понимается не C := A XOR B, а какой-нибудь алгоритм, работающий быстрее моего. Как именно работающий - неважно.
2 Real: твой код таки медленнее - по моим расчетам в 8 раз.
2 Pavia: буду твой проверять :-)
Пусик (2006-06-06 12:02:00) [9]
> begin...end © (06.06.06 11:37) [57]
>
> > Пусик © (06.06.06 10:52) [55]
>
> И что? Вы, насколько я понял по [53], согласны с тем, что
> строки в Lines нумеруются с единицы?
Конечно не согласна. :-)
Про такое поведение я только недавно узнала. В исходниках видно, почему так происходит. Хотя и непонятно, зачем такое сделано.
begin...end (2006-06-06 11:37:00) [10]> Пусик © (06.06.06 10:52) [55]
И что? Вы, насколько я понял по [53], согласны с тем, что строки в Lines нумеруются с единицы? Если так, просьба подтвердить это кодом -- возьмите Memo с двумя строчками, и, обратившись к Lines[1], получИте самую первую строчку.
По поводу кода из [55] могу только сказать, что меня такое поведение не удивляет. И порекомендовать вспомнить, что Memo.Lines -- это не TStringList, и список Lines в Memo вообще не является контейнером строк.
MBo (2006-06-06 11:07:00) [11]>Пусик
Несколько странный спор.
откуда взято [51] - я не знаю, да и вообще про индексацию с единицы - неправда.
Твой пример [55] не противоречит begin...end © (06.06.06 07:53) [54]
Пусик (2006-06-06 10:52:00) [12]
> begin...end © (06.06.06 07:53) [54]
> В самом визуальном компоненте её как не было, так и не будет.
Выполняю код:
Memo1.Lines.Clear;
Memo1.Lines[0] := 'test0';
Вижу:
В Memo появилась строка 'test0'
Выполняю далееMemo1.Lines[1] := 'test1';
В Memo появилась строка 'test1'
begin...end (2006-06-06 07:53:00) [13]> Пусик © (05.06.06 22:26) [53]
> Потому что визуальные компоненты так запрограммированы.
Как "так"? Первая строка в Memo -- это строка с индексом 0, а не 1.
> Если ее нет, она тут же создается.
В самом визуальном компоненте её как не было, так и не будет. Просто в случае запроса несуществующей строки возвратится строка нулевой длины.
Пусик (2006-06-05 22:26:00) [14]
> А почему 1?
Потому что визуальные компоненты так запрограммированы.
Строка с номером 0 всегда присутствует. Если ее нет, она тут же создается.
ПОэтому невозможно для визуальных наследников получить ошибку при обращении к несуществующей строке с номером Count, Например, TMemo никогда не возвратит ошибку при обращении к Memo.Lines[Memo.Lines.Count].
В отличие от TStringList.
begin...end (2006-06-05 21:42:00) [15]> Pavia © (05.06.06 21:37) [51]
> А почему 1?
А я знаю? У меня в справке такого нет. Да и оффтопик.
Pavia (2006-06-05 21:37:00) [16]Будем. Я у же сознался.
Lines property (TCustomMemo)
Warning: Unlike most TStrings objects, the Lines property stores its lines in a 1-based array, not a zero-based array.
А почему 1?
begin...end (2006-06-05 21:33:00) [17]> Pavia © (05.06.06 21:28) [48]
А FreePascal-то тут причём, уважаемый? В [34] и [36] Вы разве не со справкой Delphi спорили? За словеса будем отвечать, или как?
Rial (2006-06-05 21:30:00) [18]Pavia © (05.06.06 21:09) [43]
Да, упрямства тебе не занимать.
Попробуй, кстати, вот такую фичу, проверял под Delphi 2006, не знаю точно,
будет ли под остальными версиями работать:
Var
I : Integer;
Tmp : String[2];
begin
Tmp:='1';
for I := 1 to 5 do
If (I = 3) then begin
Tmp:='4';
Break;
end else
Tmp:=IntToStr(I);
Try
I:=TryStrToInt(Tmp);
Except
RunError(17);
ShowMessage('Ошибка !');
Exit;
end;
ShowMessage(IntToStr(I));
end;
Вовращает точно 4, сам проверял !
Так что ты прав, тут разработчики Delphi чего - то не учли.
Кстати, не могу сам разобраться, почему при ошибке в
I:=TryStrToInt(Tmp);
не выводится окно с сообщением об ошибке.
Если знаешь, что я не так сделал, помоги.
Pavia (2006-06-05 21:28:00) [19]Я же говорю Free pascal.
begin...end (2006-06-05 21:25:00) [20]> Pavia © (05.06.06 21:09) [43]
Версия Delphi -- ?