Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [SSE2] Помогите исправить ошибки в функции, данные, взятие модуля вещ числа и др. 
V
    Опции темы
marcusmae
Дата 4.5.2008, 19:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: нет
Всего: 39



Всем, привет,

Мучительно вспоминаю ассемблер. Вот мой код :

Код

.686
.model flat
.XMM
option casemap: none
.data
half real8 0.5
amsk dd 2147483647                ; 0x7fffffff
.code
_XMM_F@24 proc                ; (const __m128d q_LeftRight, const double V)
    push ebp
    mov    ebp, esp
    movsd    xmm1, QWORD PTR [ebp+8]    ; pick V on xmm1
    mulsd    xmm1, QWORD PTR half    ; V := 0.5 * V
    movsd    xmm2, QWORD PTR amsk    ; double abs value bit mask
    andpd    xmm2, xmm1            ; abs(0.5 * V) on xmm2
    movsd    xmm3, xmm2            ; abs(0.5 * V) on xmm3
    addsd    xmm2, xmm1            ; 0.5 * V + abs(0.5 * V)
    subsd    xmm1, xmm3            ; 0.5 * V - abs(0.5 * V)
    unpcklpd xmm2, xmm1            ; (0.5 * V + abs(0.5 * V), 0.5 * V - abs(0.5 * V))
    mulpd    xmm0, xmm2            ; * q_LeftRight
    mov    esp, ebp
    pop    ebp
    ret    0
_XMM_F@24 endp
end


Он должен быть эвивалентен

Код

__m128d F(
    const __m128d q_LeftRight, const double V) {

    const double vHalf = 0.5 * V, absVHalf = abs(vHalf);
    return _mm_mul_pd(q_LeftRight,
        _mm_set_pd(vHalf + absVHalf, vHalf - absVHalf));
}


или, если формулой, то

Код

result = { q_Left * (0.5 * V + abs(0.5 * V)), q_Right * (0.5 * V - abs(0.5 * V)) }


Но пока неэквивалентен smile Сомневаюсь, что я правильно объявил константу и правильно слизал её в регистр. Модуль вроде, так считают? И не перепутаны ли аргументы unpcklpd? Поправьте, пожалуйста.


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
sgi1981
Дата 7.5.2008, 01:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 284
Регистрация: 16.3.2006

Репутация: 1
Всего: 10



Цитата

Сомневаюсь, что я правильно объявил константу и правильно слизал её в регистр.


Действительно, я тоже сомневаюсь

может надо вот так объявить amsk

Код

amsk dq 7fffffffffffffffh;



--------------------
Тело в нашем пространстве - есть часть пространства, в которой пространство обладает дисторсией относительно внешнего пространства.
PM MAIL   Вверх
marcusmae
Дата 7.5.2008, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: нет
Всего: 39



sgi1981, спасибо, в этом действительно была ошибка. Ещё я заметил, что unpcklpd пакует аргументы таки в обратном порядке, и что в конце должно стоять ret 8.

Вот код со всеми изменениями :

Код

.686
.model flat
.XMM
option casemap: none
.data
half real8 0.5
amsk dq 7fffffffffffffffh
.code
_XMM_F@24 proc                        ; (const __m128d q_LeftRight, const double V)
    push ebp
    mov    ebp, esp
    movsd    xmm1, QWORD PTR [ebp+8]                                 ; pick V on xmm1
    mulsd    xmm1, QWORD PTR half                                ; V := 0.5 * V
    movsd    xmm2, QWORD PTR amsk                                ; double abs value bit mask
    andpd    xmm2, xmm1                    ; abs(0.5 * V) on xmm2
    movsd    xmm3, xmm2                    ; abs(0.5 * V) on xmm3
    addsd    xmm2, xmm1                    ; 0.5 * V + abs(0.5 * V)
    subsd    xmm1, xmm3                    ; 0.5 * V - abs(0.5 * V)
    unpcklpd xmm1, xmm2                    ; (0.5 * V + abs(0.5 * V), 0.5 * V - abs(0.5 * V))
    mulpd    xmm0, xmm1                    ; * q_LeftRight
    mov    esp, ebp
    pop    ebp
    ret    8
_XMM_F@24 endp
end


А вот для него "стенд", проверяющий совпадение результатов с функцией высокого уровня :

Код

// XMMTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <intrin.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <iostream>

__m128d F(
    const __m128d q_LeftRight, const double V) {

    const double vHalf = 0.5 * V, absVHalf = abs(vHalf);
    return _mm_mul_pd(q_LeftRight,
        _mm_set_pd(vHalf + absVHalf, vHalf - absVHalf));

}

extern "C" __m128d __stdcall XMM_F(
    const __m128d q_LeftRight, const double V);


int _tmain(int argc, _TCHAR* argv[])
{
    const int ntests = 1000;
    for (int itest = 0; itest < ntests; itest++)
    {
        srand((unsigned)time(NULL));

        double V = ((double)rand() - rand()) * (double)rand() / rand() * (double)itest / ntests;
        __m128d q_LeftRight = _mm_set_pd((double)rand() / rand(), (double)rand() / rand());

        const __m128d
            resultAsm = XMM_F(q_LeftRight, V),
            resultControl = F(q_LeftRight, V);

        _CRT_ALIGN(16) double resultAsmValues[2]; 
        _mm_store_pd(resultAsmValues, resultAsm);
        _CRT_ALIGN(16) double resultControlValues[2]; 
        _mm_store_pd(resultControlValues, resultControl);

        std::cout << "Asm : " <<
            resultAsmValues[0] << " " << resultAsmValues[1];
        std::cout << ", Control : " <<
            resultControlValues[0] << " " << resultControlValues[1] << std::endl;
        if ((resultAsmValues[0] != resultControlValues[0]) ||
            (resultAsmValues[1] != resultControlValues[1]))
        {
            std::cout << "Different results!" << std::endl;
            break;
        }
    }

    std::cout << "Done." << std::endl;
    std::cin.get();

    return 0;
}


Весь проект тоже присоединён - может кому-то пригодится, как туториал.

Если ещё где-то ошибки или я плохо сделал - скажите, пожалуйста.

Присоединённый файл ( Кол-во скачиваний: 1 )
Присоединённый файл  XMMTest.rar 720,70 Kb


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Asm для Windows/DOS"
MAKCim
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой КОД.
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim.

 
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Asm для Windows/Dos | Следующая тема »


 




[ Время генерации скрипта: 0.0739 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.