Форум: "Прочее";
Текущий архив: 2007.06.03;
Скачать: [xml.tar.bz2];
ВнизМожно ли как то оптимизировать данный участок кода Найти похожие ветки
← →
DVM © (2007-05-08 14:42) [0]
type
PFColor =^TFColor;
TFColor = packed record
b,g,r: Byte;
end;
TMatrixItem = record
Blue: Cardinal;
Green: Cardinal;
Red: Cardinal;
Sum: Cardinal;
end;
PMatrixItem = ^TMatrixItem;
var
pmi: PMatrixItem;
pc: PFColor;
//------------------------
inc(pmi^.blue, pc^.b);
inc(pmi^.green, pc^.g);
inc(pmi^.red, pc^.r);
inc(pmi^.sum);
Inc(pc);
//-------------------------
Отчеркнутый фрагмент выполняется сотни тысяч раз. Можно ли как ускорить эти операции?
← →
Ega23 © (2007-05-08 14:52) [1]На асме его написать?
← →
DVM © (2007-05-08 14:53) [2]
> На асме его написать?
Не владею в такой степени, чтобы обставить компилятор Delphi в плане скорости.
← →
X9 © (2007-05-08 14:55) [3]Большой разницы между данным фрагментом (при использовании оптимизации) и его ASM-вариантом быть не должно.
← →
DVM © (2007-05-08 14:56) [4]Тут прямо хочется как-то одним действием увеличить все три переменных blue, green, red :)
← →
MBo © (2007-05-08 14:59) [5]>одним действием увеличить все три переменных blue, green, red :)
для этого MMX можно использовать, но накладные расходы на подготовку данных будут значительны, так что выигрыша может и не быть
← →
X9 © (2007-05-08 14:59) [6]Одним действие не получится, ибо 3 cardinal в один 32-битный регистр не поместятся. А почему именно Cardinal? Если это RGB, то Byte хватит за глаза. А если Byte, то уже есть возможность немного схитрить.
← →
DVM © (2007-05-08 15:02) [7]
> А почему именно Cardinal?
Вычисляется средний цвет прямоугольного фрагмента изображения.
Cardinal - это суммы значений точек в клетке по каналам.
Так сделано для ускорения работы - после суммирования всех точек в клетке вычисляется средний цвет один раз.
← →
MBo © (2007-05-08 15:31) [8]
var
ca: array of TFColor;
mi: TMatrixItem;
pc: PFColor;
i, N: Integer;
t: DWord;
begin
N := 1024*1024*64;
SetLength(ca, N);
FillChar(mi, SizeOf(mi), 0);
pc := @ca[0];
t := GetTickCount;
for i := 0 to N - 1 do begin
inc(mi.blue, pc^.b);
inc(mi.green, pc^.g);
inc(mi.red, pc^.r);
inc(mi.sum);
Inc(pc);
end;
Caption := IntToStr(mi.Sum + mi.Blue +mi.Green +mi.Red) +" " + IntToStr(GetTickCount - t);
end;
Хм... Этот код для 64 мегапикселов (192 мегабайта) выполняется у меня за 453 мс, т.е. скорость обработки 150 мегапикселов в секунду. Мало? ;)
← →
Rouse_ © (2007-05-08 15:34) [9]
type
PFColor =^TFColor;
TFColor = packed record
b,g,r: Byte;
end;
TMatrixItem = record
Blue: Cardinal;
Green: Cardinal;
Red: Cardinal;
Sum: Cardinal;
end;
PMatrixItem = ^TMatrixItem;
procedure ModifyMatrix(MatrixItems: PMatrixItem; Color: PFColor;
const MatrixItemsCount: Integer); assembler;
asm
push eax
push ebx
push ecx
push edx
push edi
push esi
mov esi, eax // MatrixItems
mov bx, [edx]
mov dl, [edx + 2] // Color
@loop:
mov eax, [esi]
add al, bl
mov [esi], eax
mov eax, [esi + 4]
add al, bh
mov [esi + 4], eax
mov eax, [esi + 8]
add al, dl
mov [esi + 8], eax
inc [esi + 12]
add esi, 16
loop @loop
pop esi
pop edi
pop edx
pop ecx
pop ebx
pop eax
end;
procedure TForm5.Button1Click(Sender: TObject);
var
pmi, pmiTmp: PMatrixItem;
pc: TFColor;
I: Integer;
begin
GetMem(pmi, SizeOf(TMatrixItem) * 4);
try
pc.b := 10;
pc.g := 20;
pc.r := 30;
pmiTmp := pmi;
for I := 1 to 4 do
begin
pmiTmp^.Blue := I * 10;
pmiTmp^.Green := I * 11;
pmiTmp^.Red := I * 12;
pmiTmp^.Sum := I * 13;
Memo1.Lines.Add(Format("%d.%d.%d.%d",
[pmiTmp^.Blue, pmiTmp^.Green, pmiTmp^.Red, pmiTmp^.Sum]));
Inc(pmiTmp);
end;
ModifyMatrix(pmi, @pc, 4);
pmiTmp := pmi;
for I := 0 to 3 do
begin
Memo1.Lines.Add(Format("%d.%d.%d.%d",
[pmiTmp^.Blue, pmiTmp^.Green, pmiTmp^.Red, pmiTmp^.Sum]));
Inc(pmiTmp);
end;
finally
FreeMem(pmi);
end;
end;
← →
DVM © (2007-05-08 15:35) [10]
> Мало? ;)
Я детектор движения пишу. Сейчас скорость 500 fps при размере кадра 640*480 на одном ядре. Цель -1000 FPS. Но видимо в этом участе кода уже предел - буду другие места мучить. :)
← →
Rouse_ © (2007-05-08 15:38) [11]Не вот так проще:
procedure ModifyMatrix(MatrixItems: PMatrixItem; Color: PFColor;
const MatrixItemsCount: Integer); assembler;
asm
push eax
push ebx
push ecx
push edx
mov bx, [edx]
mov dl, [edx + 2]
@loop:
add [eax], bl
add [eax + 4], bh
add [eax + 8], dl
inc [eax + 12]
add eax, 16
loop @loop
pop edx
pop ecx
pop ebx
pop eax
end;
← →
DVM © (2007-05-08 15:52) [12]
> Rouse_ © (08.05.07 15:38) [11]
У меня цикл с 1 а не с нуля
← →
Rouse_ © (2007-05-08 15:53) [13]А этому коду пофигу... Он знает размер буффера и начальный адрес буффера. Хоть с десятки начинай
← →
DVM © (2007-05-08 16:00) [14]
> Rouse_ © (08.05.07 15:53) [13]
Тогда че-то не так
Было и работает:
for cy := 1 to ty do
begin
for cx := 1 to tx do
begin
inc(pmi^.blue, pc^.b);
inc(pmi^.green, pc^.g);
inc(pmi^.red, pc^.r);
Inc(pc);
end;
inc(integer(pc), Delta);
end;
pmi^.sum := ty * tx;
Стало, но не работает:
for cy := 1 to ty do
begin
ModifyMatrix(pmi, pc, tx);
inc(integer(pc), Delta);
end;
pmi^.sum := ty * tx;
← →
DVM © (2007-05-08 16:10) [15]
> > Rouse_ ©
У тебя в цикле на ASM вроде указатель pc не сдвигается.
← →
Rouse_ © (2007-05-08 16:11) [16]Пропустил что второй параметр у тебя тоже массив :)
Тогда:procedure ModifyMatrix(MatrixItems: PMatrixItem; Color: PFColor;
const MatrixItemsCount: Integer); assembler;
asm
push eax
push ebx
push ecx
push edx
@loop:
mov bx, [edx]
add [eax], bl
add [eax + 4], bh
mov bl, [edx + 2]
add [eax + 8], bl
inc [eax + 12]
add eax, 16
add edx, 3
loop @loop
pop edx
pop ecx
pop ebx
pop eax
end;
← →
DVM © (2007-05-08 16:11) [17]Не я неправ, все на месте
← →
Rouse_ © (2007-05-08 16:13) [18]Эээ, погоди. Вот это не то что было в начале:
for cy := 1 to ty do
begin
for cx := 1 to tx do
begin
inc(pmi^.blue, pc^.b);
inc(pmi^.green, pc^.g);
inc(pmi^.red, pc^.r);
Inc(pc);
end;
inc(integer(pc), Delta);
end;
pmi^.sum := ty * tx;
← →
Rouse_ © (2007-05-08 16:15) [19]короче на пальцах...
Мой код принимает на вход два массива PMatrixItem и PFColor, каждый цветовой элемент первого массива увеличивается на значение цвета из второго массива а pmi^.sum просто увеличивается на единицу... Оно?
← →
DVM © (2007-05-08 16:16) [20]
> Эээ, погоди. Вот это не то что было в начале:
Да, я знаю, я поправил твой код там одна строка лишняя получается, но все равно не фурычит че-то.
Я так понял твоя функция это замена внутреннего цикла?
← →
Rouse_ © (2007-05-08 16:17) [21]угу
← →
DVM © (2007-05-08 16:19) [22]
> Оно?
Оно вроде. pmi^.sum можно выкинуть из цикла оно и так рассчитывается.
← →
DVM © (2007-05-08 16:21) [23]
> угу
Или я че-то непонимаю, но в результате замены все работает не так как ранее.
← →
Rouse_ © (2007-05-08 16:22) [24]Ну я как твою задачу понял - так ее и реализовал :)
Либо неверно я понял, либо ты ее неверно описал :)
← →
DVM © (2007-05-08 16:24) [25]Короче вот:
Было:
for cy := 1 to ty do
begin
//ModifyMatrix(pmi, pc, tx);
for cx := 1 to tx do
begin
inc(pmi^.blue, pc^.b);
inc(pmi^.green, pc^.g);
inc(pmi^.red, pc^.r);
pmi^.sum := ty * tx;
Inc(pc);
end;
inc(integer(pc), Delta);
end;
Меняем:
for cy := 1 to ty do
begin
ModifyMatrix(pmi, pc, tx);
//for cx := 1 to tx do
//begin
//inc(pmi^.blue, pc^.b);
//inc(pmi^.green, pc^.g);
//inc(pmi^.red, pc^.r);
//pmi^.sum := ty * tx;
//Inc(pc);
//end;
inc(integer(pc), Delta);
end;
Где:procedure ModifyMatrix(MatrixItems: PMatrixItem; Color: PFColor;
const MatrixItemsCount: Integer); assembler;
asm
push eax
push ebx
push ecx
push edx
@loop:
mov bx, [edx]
add [eax], bl
add [eax + 4], bh
mov bl, [edx + 2]
add [eax + 8], bl
inc [eax + 12]
add eax, 16
add edx, 3
loop @loop
pop edx
pop ecx
pop ebx
pop eax
end;
Не работает.
← →
DVM © (2007-05-08 16:25) [26]pmi^.sum := ty * tx;
только надо убрать в первом коде
← →
Rouse_ © (2007-05-08 16:26) [27]А, ну тогда естественно не так...
Сек...
← →
Rouse_ © (2007-05-08 16:29) [28]Вот это закоментрарь:
//inc [eax + 12]
//add eax, 16
← →
DVM © (2007-05-08 16:33) [29]Один фиг, смотри:
Постараюсь без неточностей:
Было:
for cy := 1 to ty do
begin
//ModifyMatrix(pmi, pc, tx);
for cx := 1 to tx do
begin
inc(pmi^.blue, pc^.b);
inc(pmi^.green, pc^.g);
inc(pmi^.red, pc^.r);
Inc(pc);
end;
inc(integer(pc), Delta);
end;
pmi^.sum := ty * tx;
Стало:
for cy := 1 to ty do
begin
ModifyMatrix(pmi, pc, tx);
inc(integer(pc), Delta);
end;
pmi^.sum := ty * tx;
Где:
procedure ModifyMatrix(MatrixItems: PMatrixItem; Color: PFColor;
const MatrixItemsCount: Integer); assembler;
asm
push eax
push ebx
push ecx
push edx
@loop:
mov bx, [edx]
add [eax], bl
add [eax + 4], bh
mov bl, [edx + 2]
add [eax + 8], bl
//inc [eax + 12]
//add eax, 16
add edx, 3
loop @loop
pop edx
pop ecx
pop ebx
pop eax
end;
Это не одно и то же выходит.
← →
Rouse_ © (2007-05-08 16:37) [30]Ты лучше результаты первого и второго покажи... Что у тебя на входе находится в pmi^ и на выходе в момент выполнения inc(integer(pc), Delta);
← →
DVM © (2007-05-08 16:47) [31]
> Rouse_ ©
А какая строка в твоем коде отвечает за количество оборотов цикла?
← →
Rouse_ © (2007-05-08 16:49) [32]const MatrixItemsCount: Integer
Указывает на размер буффера во втором параметре. т.е. кол-во элементов типа ТFColor
← →
DVM © (2007-05-08 16:54) [33]
> Rouse_ © (08.05.07 16:49) [32]
Теперь мне все понятно, подумаю сам дальше. Твоя функция на 10% быстрее вроде как чем мой код на паскале, но почему то дает ложные срабатывания детектора, т.е. в pmi^ где то заносятся левые значения.
Почему - неясно пока.
Результаты тут привести проблематично - я смотрю уже на последствия изменений - когда сравниваются два кадра изображения, сами же значения в pmi^ мне мало о чем скажут. На входе там нули.
← →
Rouse_ © (2007-05-08 16:56) [34]
> в pmi^ где то заносятся левые значения.
Вероятно размер буффера более меньший, чем указан в третьем параметре...
← →
Sapersky (2007-05-08 17:21) [35]procedure GetSumA(Src : PFColor; Dst : PMatrixItem; Count : Integer);
asm
push ebx
push esi
push edi
push edx
mov esi, eax // Src -> esi
mov eax, edx
mov ebx, [eax] // unpacking Dst to ebx, edx, edi
mov edx, [eax + 4]
mov edi, [eax + 8]
@loop:
movzx eax, byte ptr [esi]
add ebx, eax // b
movzx eax, byte ptr [esi + $01]
add edx, eax // g
movzx eax, byte ptr [esi + $02]
add edi, eax // r
add esi, 3
dec ecx
jnz @loop
mov eax, edx
pop edx
mov [edx], ebx
mov [edx + 4], eax
mov [edx + 8], edi
pop edi
pop esi
pop ebx
end;
pmi.blue, pmi.green, pmi.red хранятся в регистрах, за счёт чего получается существенно быстрее.
Копирайт, скажу честно, принадлежит дельфийскому оптимизатору. Вот это даёт практически аналогичный результат:
procedure GetSum(Src : PFColor; Dst : PMatrixItem; Count : Integer);
Var n, r, g, b : Integer;
begin
b := Dst.Blue; g := Dst.Green; r := Dst.Red;
for n := 0 to Count - 1 do begin
inc(r, Src.b);
inc(g, Src.g);
inc(b, Src.r);
Inc(Src);
end;
Dst.Blue := b; Dst.Green := g; Dst.Red := r;
end;
но присвоение начальных значений r,g,b занимает один из регистров, и получается немного медленнее. Если присваивать 0 - скорость такая же, как и у asm.
← →
DVM © (2007-05-08 17:36) [36]
> Sapersky (08.05.07 17:21) [35]
Вот с твоим вариантом проблем нет - работает нормально.
мой вариант - 450 fps
GetSum 470
GetSumА 550
Вот только непонятен мне посл вариант немного.
PS. Хочу сделать (точнее сделал) детектор движения, как расширение FastDIB.
← →
Sapersky (2007-05-08 19:35) [37]Вот только непонятен мне посл вариант немного.
Это практически копия CPU window от GetSum.
movzx eax, byte ptr [esi]
это то же самое что и
xor eax, eax
mov al, [esi]
но быстрее, несмотря даже на то, что xor можно вынести из цикла.
Можно вообще избавиться от asm, если использовать GetSum вот в таком варианте:
procedure GetSum(Src : PFColor; Dst : PMatrixItem; Count : Integer);
Var n, r, g, b : Integer;
begin
b := 0; g := 0; r := 0;
for n := 0 to Count - 1 do begin
inc(r, Src.b);
inc(g, Src.g);
inc(b, Src.r);
Inc(Src);
end;
Dst.Blue := b; Dst.Green := g; Dst.Red := r;
end;
Var mi : TMatrixItem;
for cy := 1 to ty do begin
GetSum(pc, @mi, tx);
Inc(pmi.blue, mi.blue);
Inc(pmi.green, mi.green)
Inc(pmi.red, mi.red);
<...>
скорость должна быть такая же, что и с GetSumA.
Так что ассемблер знать надо, но писать на нём вовсе не обязательно (за исключением MMX/SSE, но это штука весьма специфичная и далеко не всегда применимая).
PS. Хочу сделать (точнее сделал) детектор движения, как расширение FastDIB.
В смысле выложить код? Это можно посмотреть, глядишь, ещё чего оптимизируем.
← →
DVM © (2007-05-09 13:39) [38]
> Sapersky (08.05.07 17:21) [35]
А ведь все таки и твоя функция работает не совсем правильно, я сразу и не заметил.
Правильно работает, только если писать так:
procedure GetSum(var Src : PFColor; var Dst : PMatrixItem; Count : Integer);
Var n, r, g, b : Integer;
begin
b := Dst.Blue; g := Dst.Green; r := Dst.Red;
for n := 0 to Count - 1 do
begin
inc(r, Src.b);
inc(g, Src.g);
inc(b, Src.r);
Inc(Src);
end;
Dst.Blue := b; Dst.Green := g; Dst.Red := r;
end;
но с var медленно очень, в два раза медленнее.
← →
DVM © (2007-05-09 13:44) [39]
> В смысле выложить код? Это можно посмотреть, глядишь, ещё
> чего оптимизируем.
Да, но сначала его причесать надо, у меня там пока много спорных моментов в плане и скорости и функциональности. Детектор должен быть очень быстрым и несложным - в духе FastDIB. Собственно почти уже готово.
← →
DVM © (2007-05-09 14:36) [40]А вот так все работает очень хорошо. Но пришлось отказаться от доп процедуры, ибо доп процедура работает правильно только при указании ключевого слова var, но это медленно.
Итак, было (510 fps):for cy := 1 to ty do
begin
for cx := 1 to tx do
begin
inc(pmi^.blue, pc^.b);
inc(pmi^.green, pc^.g);
inc(pmi^.red, pc^.r);
Inc(pc);
end;
inc(integer(pc), Delta);
end;
Стало (660 fps):
for cy := 1 to ty do
begin
b := 0; g := 0; r := 0;
for CX := 1 to TX do
begin
inc(B, pc^.b);
inc(g, pc^.g);
inc(R, pc^.r);
Inc(PC);
end;
mi.Blue := b; mi.Green := g; mi.Red := r;
Inc(pmi.blue, mi.blue);
Inc(pmi.green, mi.green);
Inc(pmi.red, mi.red);
inc(integer(pc), Delta);
end;
Код стал странноват, но быстрее на 20 процентов.
Интересно, а еще быстрее можно?
← →
oxffff © (2007-05-09 15:33) [41]
> Интересно, а еще быстрее можно?
Можно.
Software Optimization Guide for AMD Family 10h Processors
http://www.amd.com/us-en/assets/content_type/white_p…ch_docs/40546.pdf
← →
Sapersky (2007-05-09 22:43) [42]А ведь все таки и твоя функция работает не совсем правильно, я сразу и не заметил.
Правильно работает, только если писать так:
procedure GetSum(var Src : PFColor; var Dst : PMatrixItem; Count : Integer);
Разумеется, указатель Src, если его передавать по значению (без var), после выполнения процедуры не инкрементируется. Ну а вручную инкрементировать трудно, что ли:
inc(integer(pc), Delta + tx * 3);
или вообще без указателей:
GetSum(@FDIB.Pixels24[cy, 1], @mi, tx);
т.к. во внешнем (вертикальном) цикле "ловить блох" не имеет смысла, да и TFastDIB.Pixels это не TBitmap.Pixels.
Интересно, а еще быстрее можно?
Можно всё-таки попробовать MMX... сейчас прикинул - получается 3 операции на пиксель вместо 6. Но для этого нужно:
1) Использовать 32-битные картинки вместо 24-битных. Или разложить 24 на 3 по 8, хотя это по многим причинам менее удобно.
2) Начало обрабатываемой области должно быть выравнено на 8 байт, т.е. на 2 пикселя, размер желательно тоже.
3) Обрабатывать за один вызов не более 65536 пикселей, т.к. размер счётчиков придётся сократить до word. Впрочем, это как раз не проблема.
← →
DVM © (2007-05-09 23:01) [43]
> Разумеется, указатель Src, если его передавать по значению
> (без var), после выполнения процедуры не инкрементируется.
>
Да, я уже понял. Собственно меня вариант без использования доп процедуры даже больше устраивает.
> Можно всё-таки попробовать MMX...
> Использовать 32-битные картинки вместо 24-битных.
Не, отпадает - при конвертации/разложении потеряем весь прирост скорости.
← →
Fenik © (2007-05-10 15:06) [44]> DVM ©
> for cy := 1 to ty do
> begin
> b := 0; g := 0; r := 0;
> for CX := 1 to TX do
> begin
> inc(B, pc^.b);
> inc(g, pc^.g);
> inc(R, pc^.r);
> Inc(PC);
> end;
> mi.Blue := b; mi.Green := g; mi.Red := r;
> Inc(pmi.blue, mi.blue);
> Inc(pmi.green, mi.green);
> Inc(pmi.red, mi.red);
> inc(integer(pc), Delta);
> end;
А что такое mi? Может проще:
Inc(pmi.blue, b);
Inc(pmi.green, g);
Inc(pmi.red, r);
а то 3 лишних присваивания.
← →
Fenik © (2007-05-10 15:06) [45]> DVM ©
> for cy := 1 to ty do
> begin
> b := 0; g := 0; r := 0;
> for CX := 1 to TX do
> begin
> inc(B, pc^.b);
> inc(g, pc^.g);
> inc(R, pc^.r);
> Inc(PC);
> end;
> mi.Blue := b; mi.Green := g; mi.Red := r;
> Inc(pmi.blue, mi.blue);
> Inc(pmi.green, mi.green);
> Inc(pmi.red, mi.red);
> inc(integer(pc), Delta);
> end;
А что такое mi? Может проще:
Inc(pmi.blue, b);
Inc(pmi.green, g);
Inc(pmi.red, r);
а то 3 лишних присваивания.
← →
DVM © (2007-05-10 15:18) [46]
> а то 3 лишних присваивания.
:) Они не лишние. Так вот быстрее чуть-чуть, как ни странно. К тому же они находятся во внешнем цикле - поэтому пофиг.
← →
Knight © (2007-05-10 16:13) [47]> [46] DVM © (10.05.07 15:18)
А если..
b := pc^.b; g := pc^.g; r := pc^.r;
for CX := 2 to TX do
begin
Inc(PC);
inc(b, pc^.b);
inc(g, pc^.g);
inc(R, pc^.r);
end;
Или что-то в этом направлении...
← →
DVM © (2007-05-10 16:20) [48]
> Knight © (10.05.07 16:13) [47]
Все пляски вокруг внутреннего цикла почти лишены смысла. А так будет даже медленнее.
← →
Knight © (2007-05-10 16:24) [49]> [48] DVM © (10.05.07 16:20)
Разве три присваивания нулей и три inc-а быстрее чем просто присваивание первых элементов и переход сразу ко вторым?
← →
Knight © (2007-05-10 16:41) [50][49] Да ещё помноженное на ty внешнего цикла...
← →
Knight © (2007-05-10 16:57) [51]А если несколько потоков запускать? %)
← →
DVM © (2007-05-10 17:36) [52]
> А если несколько потоков запускать? %)
а мой код и так будет в нескольких потоках параллельно работать в реальной программе.
← →
Sapersky (2007-05-10 18:00) [53]Ради интереса сделал-таки с MMX, только макс. кол-во обрабатываемых за вызов пикселей - 256, а не 65536, прочие условия см. [42]. Быстрее где-то в 1.2 раза.
Вот, может пригодится:
Type
PMatrixItem16 = ^TMatrixItem16;
TMatrixItem16 = record
Blue, Green, Red, Alpha: Word;
end;
procedure GetSumMMX(Src : PFColorA; Dst : PMatrixItem16; Count : Integer);
asm
shr ecx, 1
jz @exit
db $0F,$EF,$D2 /// pxor mm2, mm2
db $0F,$EF,$DB /// pxor mm3, mm3
db $0F,$EF,$E4 /// pxor mm4, mm4
@loop:
db $0F,$6F,$00 /// movq mm0, [eax]
db $0F,$6F,$C8 /// movq mm1, mm0
db $0F,$60,$CA /// punpcklbw mm1, mm2
db $0F,$68,$C2 /// punpckhbw mm0, mm2
db $0F,$FD,$D8 /// paddw mm3, mm0
db $0F,$FD,$E1 /// paddw mm4, mm1
add eax, 8
dec ecx
jnz @loop
db $0F,$FD,$DC /// paddw mm3, mm4
db $0F,$7F,$1A /// movq [edx], mm3
@exit:
end;
После цикла с обработкой:
asm
db $0F,$77 /// emms
end;
← →
DVM © (2007-05-10 18:07) [54]
> Sapersky (10.05.07 18:00) [53]
спасибо, погляжу
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2007.06.03;
Скачать: [xml.tar.bz2];
Память: 0.61 MB
Время: 0.047 c