сбой ostream с использованием выровненной памяти в куче? - PullRequest
0 голосов
/ 08 февраля 2019

Вот фиктивный код, который у меня есть, тестирующий выровненное выделение памяти в куче с «огромными» значениями:

#include <iostream>
#include <iomanip>
#include <immintrin.h>

const double ln2per12 = std::log(2.0) / 12.0;

class ApproxExp
{
public:
    long step = 1000;
    long min = -48 * step;
    long max = 48 * step;
    long range = max - min;
    long numSteps = range + 1;

    __m128 v_value_float;

    float *approxFreqMuls_Float = static_cast<float*>(_mm_malloc(sizeof(float) * numSteps, 16));

    ApproxExp() {
        long inc = min;

        for (long i = 0; i < numSteps; i++, inc++) {
            double pitch = inc / (double)step;
            double refValue = pitch * ln2per12;

            v_value_float.m128_f32[i % 4] = (float)refValue;
            if (i % 4 == 3 || i == numSteps - 1) {
                _mm_store_ps(&approxFreqMuls_Float[i % 4 == 3 ? i - 3 : i - i % 4], v_value_float);
            }
        }

        std::cout << "oct       ";
    }
    ~ApproxExp() {
        _mm_free(approxFreqMuls_Float);
    }
};

int main() {
    std::cout.precision(100);
    std::cout << std::left;

    ApproxExp approxExp;

    return 0;
}

Когда я его выполняю, «иногда» он жестоко ломается (режим выпуска, MSVC), показывая это:

enter image description here

Я не могу найти ошибку, так как не вижу кода исключения.Где я не прав?

1 Ответ

0 голосов
/ 08 февраля 2019

Если вы достигли последнего индекса, а его остаток не равен 3, запись 128 битов по индексу i - i % 4 записывает вне массива.
И тогда вы попадаете в удивительную страну неопределенного поведения.

...