У меня есть функция C# ядра, которую я пытаюсь ускорить. Предложения, касающиеся безопасного или небезопасного кода, одинаково приветствуются. Вот метод:Оптимизация переупорядочения битов
public byte[] Interleave(uint[] vector)
{
var byteVector = new byte[BytesNeeded + 1]; // Extra byte needed when creating a BigInteger, for sign bit.
foreach (var idx in PrecomputedIndices)
{
var bit = (byte)(((vector[idx.iFromUintVector] >> idx.iFromUintBit) & 1U) << idx.iToByteBit);
byteVector[idx.iToByteVector] |= bit;
}
return byteVector;
}
PrecomputedIndices представляет собой массив из следующего класса:
class Indices
{
public readonly int iFromUintVector;
public readonly int iFromUintBit;
public readonly int iToByteVector;
public readonly int iToByteBit;
public Indices(int fromUintVector, int fromUintBit, int toByteVector, int toByteBit)
{
iFromUintVector = fromUintVector;
iFromUintBit = fromUintBit;
iToByteVector = toByteVector;
iToByteBit = toByteBit;
}
}
Целью метода Interleave является копирование бит из массива uints в массив байтов. Я предварительно вычислил индекс источника и целевого массива, а также номер источника и целевого бита и сохранил их в объектах индексов. Ни один из двух соседних битов в источнике не будет смежным в целевом объекте, чтобы исключить определенные оптимизации. Чтобы дать вам представление о масштабе, проблема, над которой я работаю, имеет около 4200 измерений, поэтому «вектор» имеет 4 200 элементов. Значения в векторе варьируются от нуля до двенадцати, поэтому мне нужно использовать только четыре бита для хранения их значений в массиве байтов, поэтому мне нужно 4,200 х 4 = 16 800 бит данных или 2,100 байта вывода на вектор. Этот метод будет называться миллионы раз. Он потребляет примерно треть времени в большей процедуре, которую мне нужно оптимизировать.
ОБНОВЛЕНИЕ 1: изменение «указателей» на структуру и сжатие нескольких типов данных, так что объект был всего лишь восемью байтами (int, короткий и два байта) уменьшил процент времени выполнения от 35% до 30%.
Поскольку «Индексы» - это маленький неизменный тип, вы пытались сделать его «структурой»? –
- это 'PrecomputedIndices' массив или' List'? – thumbmunkeys
Если вы сортируете индексы по индексу ввода или вывода, вы можете вдвое уменьшить размер этой вещи, а также сделать доступ к одному из них линейным. Также, если это чередование в обычном смысле (идеальное перемещение), вам не нужны индексы. – harold