Форум: "Основная";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];
ВнизИспользование технологии MMX Найти похожие ветки
← →
alertus © (2005-05-31 17:56) [0]Может быть вопрос не совсем по Delphi, но я пытаюсь использовать технологию MMX именно на Delphi, кстати, нашел руководство по MMX для новичков:
http://www.proglib.ru/detail_book.asp?id=110
И, хотя у меня Athlon, вроде инструкции MMX у меня работают.
А вопрос такой:
регистры MM0-MM7 могут разбиваться на байты, слова, двойные слова и четверные слова и производить вычисления параллельно с несколькими байтами, словами и т.д. Но если real занимает 8 байт, это как раз регистр MMX, так в чем же их выгода, если перемножения типов real невозможно запараллелить.
Знаю, что есть еще SSE, там вроде регистры XMM0-XMM7 по 128 бит, т.е. 16 байт, т.е. два real, наверно лучше использовать его, правда я еще до этого не добрался и я еще не проверил, будут ли они у меня работать.
← →
Jeer © (2005-05-31 18:24) [1]Уже идешь, так иди.
← →
MBo © (2005-05-31 18:27) [2]MMX - только для работы с целыми числами.
SSE,SSE-2,3 - для вещественных (+ кое-что дополнительно для целых)
← →
Jeer © (2005-05-31 18:30) [3]MBo © (31.05.05 18:27) [2]
Или (дополнительно) с фиксированной точкой.
← →
Defunct © (2005-05-31 18:31) [4]> Но если real занимает 8 байт, это как раз регистр MMX, так в чем же их выгода, если перемножения типов real невозможно запараллелить.
MMX это целочисленный SIMD вычислитель. Он не умеет работать с Real.
С плавающей точкой умеют работать "SSE"/"SSE2"/"SSE3"/"3DNow!". На Athlon"e вам для той задачи (перемножения матриц) надо применить 3DNow!
← →
Defunct © (2005-05-31 18:33) [5]> На Athlon"e вам для той задачи (перемножения матриц) надо применить 3DNow!
MMX + 3DNow!
← →
alertus © (2005-05-31 18:34) [6]>Defunct ©
Да, спасибо, я как раз взялся за это, когда увидел вашу программу, но я ее не совсем понял, поэтому начал читать, теперь буду читать 3DNow.
Только мне не нравится, что моя программа будет работать только на Pentium или только на Athlon...
← →
alertus © (2005-05-31 18:35) [7]А зачем мне тогда MMX, если эта технология не для вещественных??
← →
Defunct © (2005-05-31 18:37) [8]alertus © (31.05.05 18:34) [6]
MMX у меня использовался для вычисления адреса. Ведь это тоже немаловажная операция.
← →
Defunct © (2005-05-31 18:39) [9]alertus © (31.05.05 18:34) [6]
С этим ничего не поделаешь. Придется сделать несколько функций и взависимости от процессора запускать оптимальную.
← →
гогениус (2005-05-31 20:50) [10]Athlon поддерживает и MMX и SSE, так что все у тебя будет работать
← →
Defunct © (2005-05-31 20:52) [11]гогениус (31.05.05 20:50) [10]
Не все
← →
alertus © (2005-06-01 02:04) [12]Но ведь 3DNow! оперирует над числами одинарной точности, а у меня все - двойной точности...
Я вот, например, умножаю числа:
var
r:single;
p:single;
begin
r:=2.2;
p:=3.2;
asm
movd mm0,r;
movd mm1,p;
pfmul mm0,mm1;
movd p,mm0;
femms;
end;
edit1.Text:=floattostr(p);
end;
А что, если у меня
var
r:real;
p:real;
??
← →
Defunct © (2005-06-01 03:38) [13]> Но ведь 3DNow! оперирует над числами одинарной точности
Что ж.. это особенность SSE и 3DNow, либо придется пожертвовать точностью ради скорости, либо сделать вручную компенсацию точности. Одна команда pfmul перемножает сразу 4 пары чисел. Подумайте как применить.
> r:real;
Двойная точность доступна начиная с SSE2.
А я пока попробую подумать над извращенным умножением через FP/MMX. Если что-то получится, результат выложу здесь.
← →
Defunct © (2005-06-01 04:30) [14]> Одна команда pfmul перемножает сразу 4 пары чисел.
извиняюсь две пары, а не 4..
> А я пока попробую подумать над извращенным умножением через FP/MMX.
Подумал.. ничего хорошего из этого не выходит. emms стирает все значения записанные в mm регистрах, а без emms FP возобновить работу не может.
думаю дальше ;>
← →
alertus © (2005-06-01 11:28) [15]Объясните, пожалуйста, почему не работает следующий код:
var
r:^single;
p:^single;
l:^single;
begin
getmem(r,2*sizeof(single));
getmem(p,2*sizeof(single));
l:=pointer(integer(r));
l^:=2.0;
l:=pointer(integer(r)+4);
l^:=3.0;
l:=pointer(integer(p));
l^:=4.0;
l:=pointer(integer(p)+4);
l^:=5.0;
asm
movd mm0,dword ptr [r];
movd mm1,dword ptr [p];
pfadd mm0,mm1;
movd [p],mm0;
femms;
end;
edit1.Text:=floattostr(p^);
end;
Если убрать умножение, то происходит занесение [r] в [p], все верно, а если с умножением, то ошибка вылетает: "Access violation at address..."
← →
alertus © (2005-06-01 15:01) [16]В принципе, как я понимаю, должно в mm0 заносится два вещественных числа одинарной точности: 2.0 и 3.0, а в p - 4.0 и 5.0, затем они попарно перемножаются 2*4 и 3*5, затем в [p] заносится соответственно 8.0 и 15.0, но почему-то не получается...
← →
alertus © (2005-06-01 17:53) [17]Уважаемые мастера, подскажите, пожалуйста, почему такой код работает:
var
a:array[0..9] of single;
b:array[0..9] of single;
c:real;
begin
a[3]:=2;
a[4]:=3;
b[3]:=4;
b[4]:=5;
asm
movq mm0,qword ptr [a+4*3];
movq mm1,qword ptr [b+4*3];
pfmul mm0,mm1;
movq qword ptr [a+4*3],mm0;
femms;
end;
edit1.Text:=floattostr(a[3]); //8
edit2.Text:=floattostr(a[4]); //15
end;
А такой:var
a:array of single;
b:array of single;
c:real;
begin
SetLength(a,10);
SetLength(b,10);
a[3]:=2;
a[4]:=3;
b[3]:=4;
b[4]:=5;
asm
movq mm0,qword ptr [a+4*3];
movq mm1,qword ptr [b+4*3];
pfmul mm0,mm1;
movq qword ptr [a+4*3],mm0;
femms;
end;
edit1.Text:=floattostr(a[3]); //8
edit2.Text:=floattostr(a[4]); //15
end;
Выдает ошибку??
← →
Defunct © (2005-06-01 18:07) [18]> то ошибка вылетает: "Access violation at address..."
потому что [p] это обращение непосредственно к значению переменной [p]. Компилятор вместо переменной p подставляет в скобочки адрес переменной p. Для правильной адресации должно быть так
mov eax, p
mov ..., [eax]
> В принципе, как я понимаю, должно в mm0 заносится два вещественных числа одинарной точности: 2.0 и 3.0, а в p - 4.0 и 5.0, затем они попарно перемножаются 2*4 и 3*5
Но вы же используете movd (32 bit), а надо movq (64 bit), т.е. у вас в коде подготавливается только одна пара к умножению.
> [a+4*3];
Почему 4*3?
На какой команде выдается ошибка?
> qword ptr
это не обязательно писать. movq и так подразумевает работу с rm64.
← →
alertus © (2005-06-01 19:24) [19]
> Почему 4*3?
> На какой команде выдается ошибка?
Так я получаю доступ к 4-ым элементам массивов a и b, ошибка выдается, когда я делаюmovq qword ptr [a+4*3],mm0;
Я более правильно переработал код:var
a:array of single;
b:array of single;
begin
setlength(a,10);
setlength(b,10);
a[3]:=2;
a[4]:=3;
b[3]:=4;
b[4]:=5;
asm
mov eax,a;
add eax,12;
mov ebx,b;
add ebx,12;
movq mm0,[eax];
movq mm1,[ebx];
pfadd mm0,mm1;
movq [eax],mm0;
femms;
end;
edit1.Text:=floattostr(a[3]); //8
edit2.Text:=floattostr(a[4]); //15
end;
Теперь в edit1 и edit2 текст вообще не меняется, если же я уберу весь ассемблерный код, то там выводится, как и следовало ожидать, 2 и 3.
← →
alertus © (2005-06-01 19:28) [20]Урааа, заработало:
var
a:array of single;
b:array of single;
begin
setlength(a,10);
setlength(b,10);
a[3]:=2;
a[4]:=3;
b[3]:=4;
b[4]:=5;
asm
mov eax,a;
add eax,12;
mov edx,b;
add edx,12;
movq mm0,[eax];
movq mm1,[edx];
pfmul mm0,mm1;
movq [eax],mm0;
femms;
end;
edit1.Text:=floattostr(a[3]);
edit2.Text:=floattostr(a[4]);
end;
Мне, видимо, не следовало использовать регистр ebx, он, наверно как-то еще используется...
← →
VMcL © (2005-06-01 19:53) [21]>>alertus © (01.06.05 19:28) [20]
>Мне, видимо, не следовало использовать регистр ebx, он, наверно как-то еще используется...
Да. Свободно менять можно только EAX, EDX и ECX (ну и их меньшие "аналоги"). Остальные регистры нужно сохранять и восстанавливать, если они используются.
Это описано в Delphi Help.
← →
Defunct © (2005-06-01 21:13) [22]> alertus
Не особо разбрасывайтесь командами emms/femms. Они работают медленно, т.к. полностью очищают содержимое FPU.
Выгоднее всего посчитать сразу всю матрицу, и лишь после этого выполнить femms.
ну и в асме не обязательно ставить ";" после каждой команды
← →
alertus © (2005-06-01 23:54) [23]Спасибо большое.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.04 c