#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);