Форум программистов, компьютерный форум CyberForum.ru

Не работает деструктор и ошибка при использовании SSE-команд. - C++

Восстановить пароль Регистрация
 
pr0z
Сообщений: n/a
17.11.2011, 10:50     Не работает деструктор и ошибка при использовании SSE-команд. #1
Написал класс матрицы, начал писать деструктор - начало вылазить сообщение об ошибке вида "Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)". Убираю деструктор - все работает.
Что касается SSE - написал метод суммирования матриц с его использованием, но при использовании самой SSE-функции вылазит ошибка: "Необработанное исключение в "0x00fb18db" в "matr.exe": 0xC0000005: Нарушение прав доступа при чтении "0xffffffff"." В чем может быть проблема?
Вот код программы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*matrix.h*/
#include "Windows.h"
#include <iostream>
#include <tchar.h>
#include <time.h>
#include <intrin.h>
 
class Matrix
{
public:
    float *a;
    size_t n;
 
    Matrix(size_t n);
    Matrix (size_t n, const float *a);
    Matrix (Matrix *other);
    void Mul(Matrix m1, Matrix m2);
    void mmMul(Matrix m1, Matrix m2);
    void Sum(Matrix m1, Matrix m2);
    void mmSum(Matrix m1, Matrix m2);
    void Sub(Matrix m1, Matrix m2);
    void mmSub(Matrix m1, Matrix m2);
    void Print();
    /*~Matrix();*/
};
 
/*matrix.cpp*/
#include "matr.h"
#define SIZE 10
 
Matrix::Matrix(size_t n)
    {
        this->n = n;
        a = new _declspec(align(16)) float[n*n];
    }
 
Matrix::Matrix (size_t n, const float *a)
    {
        this->n = n;
        this->a = new _declspec(align(16)) float[n*n];
        memcpy(this->a, a, n*n*sizeof(a[0]));
    }
 
Matrix::Matrix (Matrix *other)
    {
        this->n = other->n;
        this->a = new _declspec(align(16)) float[this->n*this->n];
        memcpy(this->a, other->a, n*n*sizeof(this->a[0]));
    }
 
//Matrix::~Matrix()
//{
//  delete []a;
//}
 
void Matrix::Mul(Matrix m1, Matrix m2)
{
    float tmp = 0;
    for(int i = 0; i < (int)m1.n; ++i)
    {
        for(int k = 0; k < (int)m1.n; ++k)
        {
            tmp = 0;
            for(int j = 0; j < (int)m1.n; ++j)
            {
                tmp += m1.a[m1.n*i + j]*m2.a[m1.n*j + k];
            }
            this->a[m1.n*i + k] = tmp;
        }
    }
}
 
void Matrix::Sum(Matrix m1, Matrix m2)
{
    for(int i = 0; i < (int)(m1.n*m1.n); ++i)
    {
        this->a[i] = m1.a[i] + m2.a[i];
    }
}
 
void Matrix::mmSum(Matrix m1, Matrix m2)
{
    int arrSize = this->n*this->n;
    int Counter = arrSize/4;
    __m128* pm1 = (__m128*)m1.a;
    __m128* pm2 = (__m128*)m2.a;
    __m128* pthis = (__m128*)this->a;
    for(int i = 0; i < Counter; ++i)
        pthis[i] = _mm_add_ps(pm1[i], pm2[i]);
    if(arrSize%4 != 0)
    {
        int tmp = arrSize%4;
        for(int i = arrSize - tmp; i < arrSize; ++i)
            this->a[i] = m1.a[i] + m2.a[i];
    }
}
 
void Matrix::Sub(Matrix m1, Matrix m2)
{
    for(int i = 0; i < (int)(m1.n*m1.n); ++i)
    {
        this->a[i] = m1.a[i] - m2.a[i];
    }
}
 
void Matrix::Print()
{
    for(int i = 0; i < (int)n; ++i)
    {
        for(int j = 0; j < (int)n; ++j)
        {
            _tprintf(_T("%f\t"), this->a[n*i+j]);
        }
        _tprintf(_T("\n"));
    }
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.11.2011, 10:50     Не работает деструктор и ошибка при использовании SSE-команд.
Посмотрите здесь:

C++ ошибка при использовании delete
Ошибка при использовании конструктора C++ Builder
Ошибка при использовании STL C++
C++ Ошибка при использовании метода хорд
Ошибка при использовании вектора C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
17.11.2011, 11:09     Не работает деструктор и ошибка при использовании SSE-команд. #2
Цитата Сообщение от pr0z Посмотреть сообщение
__m128* pm1 = (__m128*)m1.a;
Так нельзя делать. Данные должны быть выровнены на границу 16 байт.

Цитата Сообщение от pr0z Посмотреть сообщение
a = new _declspec(align(16)) float[n*n]
Вот честно признаюсь, первый раз такую запись вижу. Сейчас погуглю, но по моему в интернете кто-то не прав.
Хотя бы объявление тогда такое сделай: __declspec(align(16)) float *a

Т.е. есть выделение памяти в виде функции, которая выделяет на сколько-то байт больше, чем нужно для выравнивания и возвращает указатель не на начало выделенной области, а на выровненный блок в этой области. Немного сдвинуто от начала. Соответственно и при удалении нужно использовать не указатель на начало выровненной памяти, а несколько "левее". Повторюсь, new с выравниванием я вижу впервые, но не сомневаюсь, что и указатель нужно делать выровненным. Типы должны совпадать всё таки.

Добавлено через 59 секунд
_aligned_malloc и _aligned_free я функции использовал, когда выровненные данные нужны были. Про new надо погуглить...

Добавлено через 4 минуты
Вот что по этому поводу думает Майкрософт: http://msdn.microsoft.com/ru-ru/library/83ythb65.aspx

o create an array whose base is properly aligned, use _aligned_malloc, or write your own allocator. Note that normal allocators, such as malloc, C++ operator new, and the Win32 allocators return memory that will most likely not be sufficiently aligned for __declspec(align(#)) structures or arrays of structures.
Сыроежка
Заблокирован
17.11.2011, 17:47     Не работает деструктор и ошибка при использовании SSE-команд. #3
Зачем вы используете конструкцию

C++
1
this->a = new _declspec(align(16)) float[n*n];
смысл которой не понимаете.
pr0z
Сообщений: n/a
18.11.2011, 03:02     Не работает деструктор и ошибка при использовании SSE-команд. #4
Цитата Сообщение от Сыроежка Посмотреть сообщение
Зачем вы используете конструкцию

C++
1
this->a = new _declspec(align(16)) float[n*n];
смысл которой не понимаете.
Кто вам сказал, что я не понимаю ее смысл? Я не спорю с тем, что могу использовать ее неправильно, но я уверен в ее необходимости. И я пришел сюда за советом, а не для того, чтобы меня тыкали в носом в мое незнание.

Добавлено через 10 минут
Цитата Сообщение от Deviaphan Посмотреть сообщение
Добавлено через 4 минуты
Вот что по этому поводу думает Майкрософт: http://msdn.microsoft.com/ru-ru/library/83ythb65.aspx
Попробовал использовать данный вариант
C++
1
_declspec(align(16)) float *a
- сказало, что формальные параметры не будут выровнены.
В плане использования с new - да, MSDN это пишет. Однако конструкция
C++
1
_declspec(align(16))float mas[masSize]
работает. То есть в момент инициализации массива использовать ее можно, если я не прав - прошу меня поправить.
Я постараюсь конкретнее сформулировать свой вопрос: могу ли я выровнять массив данных уже внутри функции, которая его использует?
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
18.11.2011, 05:53     Не работает деструктор и ошибка при использовании SSE-команд. #5
Цитата Сообщение от pr0z Посмотреть сообщение
То есть в момент инициализации массива использовать ее можно, если я не прав - прошу меня поправить.
При инициализации массива не используется динамическое выделение памяти, а используется стек. Для стековых переменных __declspec(align(16)) применять можно и нужно. Для new использовать нельзя, что я, со свойственной мне грациозностью, нашёл в документации к компилятору.
Yandex
Объявления
18.11.2011, 05:53     Не работает деструктор и ошибка при использовании SSE-команд.
Ответ Создать тему
Опции темы

Текущее время: 05:45. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru