Сравнение двух массивов с помощью SSE и модификация третьего

Тема в разделе "WASM.BEGINNERS", создана пользователем Anton, 5 дек 2007.

  1. Anton

    Anton New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2007
    Сообщения:
    13
    Пытаюсь тут научиться, вот програмка которая производит перемножение чисел в массиве 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.
    Заранее спасибо ответевшим.
     
  2. Anton

    Anton New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2007
    Сообщения:
    13
    Неужели это так сложно, что ответить никто не может ?
    Или плз. отправьте меня туда где можно задать этот вопрос и дождаться ответа :)
     
  3. nester7

    nester7 New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2003
    Сообщения:
    720
    Адрес:
    Russia
    А что, должны?

    Отправляйся :)
     
  4. Anton

    Anton New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2007
    Сообщения:
    13
    Никто никому ничего не должен.
    Если кого-то цитируете то цитируйте полностью.
    За ссылку спасибо, с моими знаниями асма толку от нее нуль :dntknw:.
    Книжек по асму в электронном виде много, примеров с применением SSE мало (от простого к сложному).
    Топик называется WASM.BEGINNERS поэтому и спросил про сложность, может имеет смысл задать этот вопрос в другой теме. ? Кстате на этот сайт можно отсылать по любому вопросу, может тогда и топик ненужен?
     
  5. nester7

    nester7 New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2003
    Сообщения:
    720
    Адрес:
    Russia
    Скорее всего :)

    Не кипятись ты, просто не нужно писать нечто, вроде:
    Ответят, так ответять, не ответят - забей.
    В любом случае, не нужно ждать - нужно искать самому и думать.

    Так и есть :)
    Ибо вопросы задают, в основном, от невнимательного чтения, реже - от недостатка
    знаний (хм, а у кого их нынче много? :). Мало кто спросит "почему устанавливается
    такой-то флаг, хотя действие-то мы делаем вот такое?", чаще пишут
    проще - "я вот написал и не работает, разберитесь" (иногда дописывают "пожалуйста").
    Кто-то помогает, кому не в лом (не я :), кто-то не знает подробнеостей (тут я :), кто-то
    даже в топик этот не заглянет.
    Ты, главное, не кипятись :)
     
  6. Anton

    Anton New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2007
    Сообщения:
    13
    Очень часто в последнее время просматриваю форумы по программированию и вижу посты с такими советами.
    А почему у тебя вдруг возникла мысль что как только я столкнулся с проблемой Subj, то тутже помчался на форум что бы мне решение написали ?
    В общем, предлагаю закрыть наш диспут (имхо никчему не приведет), мы отклонились от темы.
    Если есть дельные мысли пишите, нет, не стоит флэймить.
     
  7. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    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):
    1.     mov     eax, 80000000h
    2.     movd    xmm0, eax
    3.     pshufd   xmm0, xmm0, 0
    4.     lea     eax, Mas1
    5.     lea     ecx, Mas2
    6.     lea     edx, Mas3
    7.     xor     ebx, ebx
    8. l1:
    9.     movaps  xmm0, [eax+ebx]
    10.     subps   xmm0, [ecx+ebx]
    11.     andps   xmm0, xmm1
    12.     movaps  [edx+ebx], xmm0
    13.     add     ebx, 16
    14.     cmp     ebx, array_size*4
    15.     brne    l1
    это реализует что-то вроде такого кода:
    (прошу прощения, если коряво, паскаля уже лет пять в руках не держал :) )
    Код (Text):
    1. ...
    2. var
    3.   Mas1, Mas2: array[1..array_size] of single;
    4.   Mas3: array[1..array_size] of dword; {не помню, как ентот тип в паскале зовется :( }
    5. ...
    6.   for i := 1 to array_size do
    7.     if Mas1[i] < Mas2[i] then
    8.       Mas3 := $80000000
    9.     else
    10.       Mas3 := 0;
    если нужно что-то более ювелирное - надо думать.
     
  8. nester7

    nester7 New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2003
    Сообщения:
    720
    Адрес:
    Russia
    Ustus
    Спасибо, а то ходют тут и не верят :)
     
  9. Anton

    Anton New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2007
    Сообщения:
    13
    Спасибо :), буду осмыслять..., я в русских книжках (Читаю Юрий Магда "Аппаратное обеспечение и эффективное программирование" + куча pdf и djvu) с трудом разбираться пытаюсь, о мануалах на англицком вообще с моими знаниями ин. яз. говорить нечего :dntknw:
    ЗЫ: Проблема в том что массивы у меня разного типа. А как сравнивать, что бы на выходе получать Mas3 типа byt не понятно. Mas3 типа byte в дальнейшем будет обрабатываться в Delphi, и с byte будет намного быстрее чем с single.
     
  10. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    Anton
    переупаковывать придется, однако... чтобы эффективно (а это значит - на регистрах) сделать сие, придется разворачивать цикл.

    побайтовая обработка примерно равноценна по производительности обработке двойными словами. И то и другое целочисленное, я имею ввиду.

    Я вижу здесь другую проблему - а средствами Дельфи можно выравнивать массив на 16 байт? А то невыровненая загрузка вполне способна схавать весьма большую часть выигрыша :dntknw:
     
  11. Anton

    Anton New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2007
    Сообщения:
    13
    Блин :dntknw: как раз сейчас думаю как это сделать, прогу вроде написал как надо, теперь немогу понять как выровнить массив на 16 байт...
     
  12. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    Anton
    Я не могу сказать, как это сделать на Дельфи, ну нет у меня практики работы с ним :dntknw:
    Но на Си это можно в крайнем случае сделать руками (в случае, если компилятор не поддерживает соответствующие директивы, или их по какой-либо причине невожможно применить). Что-то вроде:
    Код (Text):
    1. const int arr_sz = 4096; //  к примеру.
    2. char aMas1[arr_sz * sizeof(float) + 15];
    3. float* Mas1 = (float*)((unsigned)(aMas1 + 15) & ~15);
    4. // далее используем указатель Mas1 вместо массива aMas1.
    5. // ...
    Возможно, на Дельфи можно как-нибудь так извратнуться...
     
  13. Anton

    Anton New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2007
    Сообщения:
    13
    ok спасибо!!!