Re: Структурный доступ к MemoryMappedFile
От: VladCore  
Дата: 07.05.21 04:55
Оценка: 117 (1)
Здравствуйте, Sinclair, Вы писали:

S>Всем привет.

S>Разбираюсь с эффективным произвольным доступом к файлу из-под .Net.

S>Идея сводится к тому, чтобы отобразить файл в память, а затем работать с ним как со Span<T>, где T — некоторый struct тип.

S>Смысл идеи — в том, чтобы избежать какой-либо "упаковки/распаковки" или копирований данных.
S>Бегло погуглил, нашёл несколько проблем без опубликованных решений, и понял, что там не вполне понимаю, как это всё сделать корректно. Как гарантировать, что время жизни Span<T> не превысит время жизни View?
S>По идее, должен быть какой-то способ работать с View как с Memory<T>, но я пока что не вьехал, как именно это сделать.
S>Продолжаю читать всякие
S>https://github.com/dotnet/runtime/issues/37227
S>https://github.com/dotnet/runtime/issues/24805
S>и прочее. Если кто-то уже разобрался — ткните носом, куда читать.

непонятно что именно непонятно. 🙃

вот Span<int> на 2 гигабайта плюс 42 числа. без копирования упаковки распаковки.
using System;
using System.IO;
using System.IO.MemoryMappedFiles;

class Program
{
    static unsafe void Main(string[] args)
    {
        int length = (int) (2L * 1024 * 1024 * 1024 / 4 + 42);
        using (FileStream fs = new FileStream(@"v:\large.data", FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
        {
            fs.Position = length * 4L - 1;
            fs.WriteByte(0);
        }

        Console.WriteLine($"length: {length:n0}");
        using (var mmf = MemoryMappedFile.CreateFromFile(@"v:\large.data", FileMode.Open, "img-1"))
        {
            using (var accessor = mmf.CreateViewAccessor(0, length * 4L))
            {
                byte* pointer = null;
                accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref pointer);

                Span<int> arr = new Span<int>(pointer, length);
                arr[1] = 0x07070707;
                arr[length - 1] = 0x06060606;
            }
        }
    }
}


S>Как гарантировать, что время жизни Span<T> не превысит время жизни View?


необходимо, хоть и не достаточно, что бы время жизни View и Span контролировал один и тот же владелец.
Гарантировано если надо, то как в примере выше — оба экземпляра локальные.

Вот тут посложнее гайд есть про ownership, consumption и lease: https://docs.microsoft.com/en-us/dotnet/standard/memory-and-spans/memory-t-usage-guidelines

Или ты хотел что было как с Managed Heap все было просто? 😉
Отредактировано 07.05.2021 7:55 VladCore . Предыдущая версия . Еще …
Отредактировано 07.05.2021 5:02 VladCore . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.