.NET Массив ссылок - PullRequest
       2

.NET Массив ссылок

0 голосов
/ 26 января 2019

В .NET нам дается System.Span<T>, что позволяет напрямую ссылаться на непрерывную память. Обычно он создается путем предоставления ему существующего массива. Однако что, если я хочу иметь возможность создавать массив ссылок на прерывистые элементы в массиве?

Например, учитывая:

var array = new double[ 5 ] { 1, 2, 3, 4, 5 };
var span = new Span( array ); // Continuous references, [ 1, 2, 3, 4, 5 ]

Что если я захочу взять array и создать «span», который может иметь различное расположение значений, но при этом ссылаться на значение, хранящееся в массиве? Такие как:

var discontinuous = new DiscontinuousSpan[3] { 
  (reference of array[1]), 
  (reference of array[0]), 
  (reference of array[4]) };

discontinuous[ 0 ]; // 2 (reference of array[1])
discontinuous[ 1 ]; // 1 (reference of array[0])
discontinuous[ 2 ]; // 5 (reference of array[4])

Я посмотрел документацию Span<T> и понял, что это просто указатель на память фиксированной длины. Однако, с добавлением ссылок на типы значений в C # 7.2, не должны ли работать прерывистые ссылки на элементы массива? Я не вижу никаких типов .NET, которые это делают, поэтому я предполагаю, что мне придется реализовать что-то подобное с помощью пользовательского типа значения.

Разъяснение : Основная цель - иметь эту поддержку System.Numerics.Vector<T>, чтобы я мог выполнять SIMD на прерывистых ссылках.

1 Ответ

0 голосов
/ 26 января 2019

Итак, у вас есть массив с числами и вы хотите иметь отдельные ссылки на сегмент этого массива.Но Span - это особый тип значений, который нельзя обойти.Таким образом, вы должны хранить информацию, чтобы генерировать эти отдельные промежутки только тогда, когда это необходимо ...

// Here we store index and length for each desired segment
var mySegments = new (int position, int length)[] { (17, 5), (48, 19), (79, 16) };

Затем, когда необходимо получить доступ ...

double [100] Numbers = GetNumbersFromSomwhere();

public double[] GetSegment(int segmentIndex)
{
   var segment = mySegments[segmentIndex];
   var reference = new Span<double>(Numbers, segment.position, segment.length);
   return reference.ToArray();
}

Однако, этот финалToArray () создаст экземпляр нового массива объектов (который генерирует GC-давление).Поэтому, возможно, вы могли бы хранить и обращаться к своим данным в виде байтового массива (очевидно, учитывая 8 байтов длины каждого двойного числа), чтобы генерировать отдельные отрезки двойного числа.И позже, наконец, получите ваши значения с помощью функции, подобной этой, для чтения конкретного двойного числа:

    // Converts a Span into a double
    // Requires using System.Runtime.CompilerServices.Unsafe
    public static double ToDouble(ReadOnlySpan<byte> value)
    {
        if (value.Length < sizeof(double))
            throw new ArgumentOutOfRangeException(nameof(value));
        return Unsafe.ReadUnaligned<double>(ref MemoryMarshal.GetReference(value));
    }

Надеюсь, это поможет в вашем случае Vector (фиксированный тип, я нажимаю).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...