новый вектор с использованием .Net System.Numeric заполняет только половину длины вектора

#c# #.net #simd #visual-studio-debugging #system.numerics

#c# #.net #simd #visual-studio-отладка #system.numerics

Вопрос:

Я делаю цифровой фильтр и использую вектор и инструкции SIMD, чтобы ускорить его, но во время отладки я заметил, что при создании нового вектора инициализируется только половина элементов в векторе, например, при создании вектора длиной 8 только первые 4 элемента векторабудет иметь значение, остальное будет равно 0, даже если массив, который используется для создания вектора, содержит 31 элемент, отличающийся от 0. Это приводит к тому, что фильтр использует только половину коэффициентов и половину данных.

введите описание изображения здесь

Соответствующий код приведен ниже.

 var simdLength = Vector<float>.Count;
var leftOver = m_filterSize % simdLength;
    for (int i = 0; i < m_filterSize - leftOver; i  = simdLength)
    {
        var filterVector = new Vector<float>(m_filter, i);
        var dataVector = new Vector<float>(data, i);
        filteredValueVector  = filterVector * dataVector;
    }
  

После этого есть некоторый код для обработки оставшегося, но это не вектор и работает нормально.

Комментарии:

1. Это только отладочный вид … ваши данные все еще там

2. Нет, я только что провел тест, выполнив ту же математику, которая не была векторизована сразу после кода вопроса с теми же значениями, и ответы разные, поэтому кажется, что векторы действительно инициализированы неправильно

3. Я также столкнулся с этой проблемой. Я использую последнюю версию .NET Core 3.1 в 64-разрядной Windows. Я использую Vector<float>.One , и возвращаемый вектор содержит 8 записей, но только для первых 4 элементов установлено значение 1. Для остальных задано значение 0.

4. Неважно, это действительно был просто отладчик: github.com/dotnet/runtime/issues/9688 Разница в вычислениях была вызвана ошибкой в другом месте векторизованного кода.

5. Также влияет на использование .NET 5.0 в VS 2019

Ответ №1:

Это ошибка отладчика:

 int capacity = Vector<float>.Count;
float[] testVals = Enumerable.Range(0, capacity).Select(i => (float)i).ToArray();
Vector<float> testV = new(testVals);
float[] returnedVals = Enumerable.Range(0, capacity).Select(i => testV[i]).ToArray();
  

введите описание изображения здесь

Интересно, string.Join что всегда форматирует ваш вектор по своему выбору:

 Vector<int> powersOfTwo = new Vector<int>(Enumerable.Range(0, Vector<int>.Count).Select(i => 1 << i).ToArray());
string powersOfTwoString = string.Join("abc", powersOfTwo);
  

введите описание изображения здесь