Пытаюсь тут научиться, вот програмка которая производит перемножение чисел в массиве Mas1 с вектором Mas2. Что нужно дописать что бы : если число в Mas1 меньше чем в Mas2 то в Mas3 пишется 1, если наоборот то 0. Не как не могу понять как работать с операциями сравнения MMX, SSE unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; Mas1: array [0..31] of single; Mas2: array [0..3] of single; Mas3: array [0..31] of byte; implementation {$R *.dfm} procedure Ran; begin Mas2[0]:=Random(3); Mas2[1]:=Random(3); Mas2[2]:=Random(3); Mas2[3]:=Random(3); end; procedure TForm1.FormCreate(Sender: TObject); var i:integer; begin Randomize; for i:=0 to 31 do Begin Mas1:=Random(10); Mas3:=0; end; asm lea eax, Mas1 lea edx, Mas3 mov ecx, 8 @Loop: push eax push edx push ecx Call Ran pop ecx pop edx pop eax movups xmm0, [Mas2] movDQU xmm1, [eax+0]//Mas1 mulps xmm1, xmm0 movups [edx], xmm1 add eax,8*2 add edx,8*2 Loop @Loop end; end; end. Заранее спасибо ответевшим.
Неужели это так сложно, что ответить никто не может ? Или плз. отправьте меня туда где можно задать этот вопрос и дождаться ответа
Никто никому ничего не должен. Если кого-то цитируете то цитируйте полностью. За ссылку спасибо, с моими знаниями асма толку от нее нуль . Книжек по асму в электронном виде много, примеров с применением SSE мало (от простого к сложному). Топик называется WASM.BEGINNERS поэтому и спросил про сложность, может имеет смысл задать этот вопрос в другой теме. ? Кстате на этот сайт можно отсылать по любому вопросу, может тогда и топик ненужен?
Скорее всего Не кипятись ты, просто не нужно писать нечто, вроде: Ответят, так ответять, не ответят - забей. В любом случае, не нужно ждать - нужно искать самому и думать. Так и есть Ибо вопросы задают, в основном, от невнимательного чтения, реже - от недостатка знаний (хм, а у кого их нынче много? . Мало кто спросит "почему устанавливается такой-то флаг, хотя действие-то мы делаем вот такое?", чаще пишут проще - "я вот написал и не работает, разберитесь" (иногда дописывают "пожалуйста"). Кто-то помогает, кому не в лом (не я , кто-то не знает подробнеостей (тут я , кто-то даже в топик этот не заглянет. Ты, главное, не кипятись
Очень часто в последнее время просматриваю форумы по программированию и вижу посты с такими советами. А почему у тебя вдруг возникла мысль что как только я столкнулся с проблемой Subj, то тутже помчался на форум что бы мне решение написали ? В общем, предлагаю закрыть наш диспут (имхо никчему не приведет), мы отклонились от темы. Если есть дельные мысли пишите, нет, не стоит флэймить.
Anton Будем считать, что одно каменное сердце ты разжалобил Не стоит обижаться - просто по работе отдельных инструкций тебе действительно никто лучше вендора (Intel/AMD) тебе не расскажет. Поэтому открываем: Intel(R) 64 and IA-32 Architectures Software Developers's Manual #253666 #253667 (Instruction Set Reference) или AMD64 Technology - AMD64 Architecture Programmer’s Manual #26568 (128-Bit Media Instructions) и там все написано (правда, иногда с ашипками ) по операциям сравнения - все очень просто. PCMPGTD, к примеру сравнивает упакованные знаковые значения-двойные слова в источнике и приемнике и если в источнике соответствующее поле больше, чем в приемнике, заполняет его единицами, иначе - нолями. Остальные аналогично. что могу сказать сразу - невыровненные операции типа MOVUPS здорово попортят производительность, так что и не стоит огород городить... для эффективности лучше MOVAPS, при этом, конечно, следует позаботится о выравнивании. вообще задача в изначальной формулировке плохо векторизируется из-за того, что элементы массивов у тебя разного размера. Вот если бы были одинаковые, то можно было бы сочинить что-то вроде: Код (Text): mov eax, 80000000h movd xmm0, eax pshufd xmm0, xmm0, 0 lea eax, Mas1 lea ecx, Mas2 lea edx, Mas3 xor ebx, ebx l1: movaps xmm0, [eax+ebx] subps xmm0, [ecx+ebx] andps xmm0, xmm1 movaps [edx+ebx], xmm0 add ebx, 16 cmp ebx, array_size*4 brne l1 это реализует что-то вроде такого кода: (прошу прощения, если коряво, паскаля уже лет пять в руках не держал ) Код (Text): ... var Mas1, Mas2: array[1..array_size] of single; Mas3: array[1..array_size] of dword; {не помню, как ентот тип в паскале зовется :( } ... for i := 1 to array_size do if Mas1[i] < Mas2[i] then Mas3 := $80000000 else Mas3 := 0; если нужно что-то более ювелирное - надо думать.
Спасибо , буду осмыслять..., я в русских книжках (Читаю Юрий Магда "Аппаратное обеспечение и эффективное программирование" + куча pdf и djvu) с трудом разбираться пытаюсь, о мануалах на англицком вообще с моими знаниями ин. яз. говорить нечего ЗЫ: Проблема в том что массивы у меня разного типа. А как сравнивать, что бы на выходе получать Mas3 типа byt не понятно. Mas3 типа byte в дальнейшем будет обрабатываться в Delphi, и с byte будет намного быстрее чем с single.
Anton переупаковывать придется, однако... чтобы эффективно (а это значит - на регистрах) сделать сие, придется разворачивать цикл. побайтовая обработка примерно равноценна по производительности обработке двойными словами. И то и другое целочисленное, я имею ввиду. Я вижу здесь другую проблему - а средствами Дельфи можно выравнивать массив на 16 байт? А то невыровненая загрузка вполне способна схавать весьма большую часть выигрыша
Блин как раз сейчас думаю как это сделать, прогу вроде написал как надо, теперь немогу понять как выровнить массив на 16 байт...
Anton Я не могу сказать, как это сделать на Дельфи, ну нет у меня практики работы с ним Но на Си это можно в крайнем случае сделать руками (в случае, если компилятор не поддерживает соответствующие директивы, или их по какой-либо причине невожможно применить). Что-то вроде: Код (Text): const int arr_sz = 4096; // к примеру. char aMas1[arr_sz * sizeof(float) + 15]; float* Mas1 = (float*)((unsigned)(aMas1 + 15) & ~15); // далее используем указатель Mas1 вместо массива aMas1. // ... Возможно, на Дельфи можно как-нибудь так извратнуться...