@MuffinLover

Откуда здесь NAN?

https://pastebin.com/GG8uyjYT
на 185 итерации цикла M оно уходит в NAN
Помогите, пожалуйста
WTF
  • Вопрос задан
  • 245 просмотров
Решения вопроса 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Помогите, пожалуйста

Если MultiplyMatrices переписать как три обычных вложенных цикла, всё работает нормально.

float* vMultiplyMatrices(const float* matrix_1, const float* matrix_2)
{
        __m128 vector_2;//переменная для хранения значения второй матрицы
        __m128 result_vector;//переменная для записи итоговой марицы
        auto* result_matrix = (float*)_mm_malloc(N * N * sizeof(float), 16);//выделение памяти с выравниванием
(2)     //memset(result_matrix, 0, N * N * sizeof(float));
        for (int i = 0; i < N; ++i) {
                for (int j = 0; j < N; ++j) {
                        __m128 element_vector = _mm_set1_ps(matrix_1[i * N + j]);//4 позиции в одно значение
                        for (int k = 0; k < N; k += 4) {
                                vector_2 = _mm_load_ps(&matrix_2[j * N + k]);//4 значение по адресу
(1)                             result_vector = _mm_load_ps(&result_matrix[i * N + k]);
                                result_vector = _mm_add_ps(result_vector, _mm_mul_ps(element_vector, vector_2));
                                _mm_store_ps(&result_matrix[i * N + k], result_vector);
                        }
                }
        }
        return result_matrix;
}


В отмеченной (1) строке ты загружаешь в result_vector неинициализированные значения из result_matrix и дальше используешь их в арифметике. Если раскомментировать memset (2), то выполнение доходит до конца без nan.
Короче, разбирайся со своими векторными оптимизациями.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
by_kapt0xa
@by_kapt0xa
Учу кресты катаюсь на велике
я при выполнении получил ошибку в 152 строке (delete[] multed;)
возможно, вы напартичили с указателями и nan получается из мусорных значений
вы вроде на c++ пишете, а векторами не пользуетесь
вектора не будут давать ошибок при работе с указателями, и во время дебага отладчик показывает все содержимое вектора а не только 1 число
все, что связанно с указателями, new, delete надо вычеркнуть из своего кода заменить это все векторами
и матрицу лучше делать так:
int n;
    vector<float> maxrix(n * n, 0); // так плохо
    vector<vector<float>> matrix(n, move(vector<float>(n, 0))); // так хорошо


и еще для примера я тебе переписал функцию subtract, чтобы ты знал как это нормально делается
vector<vector<float>>& operator -=(vector<vector<float>>& Left, const vector<vector<float>>& Right) {
    assert(Left.size() == Right.size()); // #include <cassert>
    //ассерт выполняется только в режиме дебага. он делает твой код безопаснее
    for (size_t i = 0; i < Left.size(); i++)
    {
        vector<float>& line = Left[i];//принимает по ссылке, а не по значению.
        const vector<float>& r_line = Right[i];
        assert(line.size() == r_line.size()); // #include <cassert>
        for (size_t j = 0; j < line.size(); j++)
        {
            line[j] -= r_line[j];
        }
    }
    return Left;
}

vector<vector<float>> operator -(const vector<vector<float>>& Left, const vector<vector<float>>& Right) {
    auto copy = Left;
    copy -= Right;
    return copy;
}

const type& - значение передается по ссылке, без копирования с запретом на изменение
type& - значение передается по ссылке, без копирования, можно вносить изменения
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы