Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.048 c
1-1118071657
Петя
2005-06-06 19:27
2005.06.29
можноли создать наделфи функцию у которой неизвусное число параме


1-1117652395
Ralf
2005-06-01 22:59
2005.06.29
PopUp


1-1117777385
msgipss
2005-06-03 09:43
2005.06.29
Как обработать исключение сгенерированное в чужом объекте


3-1116318471
jiny
2005-05-17 12:27
2005.06.29
Как возвращать из запроса sum(kol) не null, а 0


14-1117707479
12DFBDDh
2005-06-02 14:17
2005.06.29
Он лайн библиотека "Архивариуса"





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский