Закрепление массивов структур, содержащих неблизкие типы c# - PullRequest
1 голос
/ 03 февраля 2020

У меня есть сценарий, в котором есть массивы структур, и я строю их пакеты (например, StructA, StructB, StructD) в объекте с указателями на их память (так как данные структуры могут быть обновлены после создания пакета). ) и я не хочу отслеживать это и перестраивать пакет, в идеале я хочу содержать все указатели для быстрого поиска.

Так, например, вот как выглядит одна из партий:

[StructLayout(LayoutKind.Sequential)]
public unsafe struct Batch<T1, T2> : IEquatable<Batch<T1, T2>> 
    where T1 : unmanaged, IComponent
    where T2 : unmanaged, IComponent
{
    public readonly int EntityId;
    public readonly T1* Component1;
    public readonly T2* Component2;

    public Batch(int entityId, T1* component1, T2* component2)
    {
        EntityId = entityId;
        Component1 = component1;
        Component2 = component2;
    }
}

Теперь изначально я просто использовал ключевое слово fixed и зацикливал массивы, принимая нужные мне структуры и получая их адрес, однако я быстро понял, что исправление работает только в рамках метода, поэтому G C все еще будет перемещать память, что означало, что через некоторое время указатели будут ссылаться на мусор.

Итак, я попытался закрепить память, однако, когда я делаю это, она взрывается, если структуры содержат bools (и я думаю chars, в основном любые структуры, которые не являются blittable). В этом сценарии все структуры должны содержать данные о типах значений, однако я не хочу применять принудительные типы данных, если это возможно, во избежание.

, так как fixed является только временным, а закрепление допускает только данные, содержащие блиты, Есть ли другой подход, который позволил бы мне получить указатели / ссылки на структуры?

Основной мотивацией для выполнения этой пакетной обработки была производительность, поскольку в идеале она обеспечивала бы последовательный доступ к памяти и, как мы надеемся, позволяла бы выполнять более предварительную выборку и кэширование на CPU, так вот почему мы сохраняем указатели, а не просто индекс для поиска (поскольку это потенциально разрушит любые предварительные выборки и поиск в кэше).

== Edit ==

Просто для ясности рассматриваемая структура представляет собой стандартную библиотеку классов. net, которая в настоящее время построена против. net стандарт 2.1.

Она также нацелена на c# 7.3, я не совсем уверен, могу ли я перейти на c# 8.0, так как потребители могут работать на. net framework или mono, поэтому, если они застряли на 7.3, возможно, потребуется подтвердить это, прежде чем я смогу обновить.

...