[Core] Отключение кеширования файлов на ОС-уровне.
От: VladCore  
Дата: 15.05.19 18:13
Оценка:
В Windows кто не в курсе отключить кеширование и чтения и записи можно в конструкторе FileStream секретной опцией:

const int FILE_FLAG_NO_BUFFERING = 0x20000000;
using (var stream = new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.Read, buffer.Length,
    (FileOptions) FILE_FLAG_NO_BUFFERING | FileOptions.WriteThrough))
{
   ....
}

Думаю это только и только в Windows.

Пока писал вопрос нагуглил что в линуксе нужно передавать O_DIRECT
# define O_DIRECT 040000

но есть ограничения: https://stackoverflow.com/a/4705680

Напомните кто gcc помнит 040000 — это по-нашему (шучу) будет 0x4000?

Интересно а в линуксе можно одновременно и FileOptions.WriteThrough и O_DIRECT передавать в опициях?

Для Windows лично проверял правда только в .NET Framework. Для линукса только что нашел.

P.S. И чтоб два раза "не вставать" на macOS все сложнее: https://stackoverflow.com/a/2307055
Отредактировано 15.05.2019 19:32 VladCore . Предыдущая версия . Еще …
Отредактировано 15.05.2019 18:39 VladCore . Предыдущая версия .
Отредактировано 15.05.2019 18:20 VladCore . Предыдущая версия .
Отредактировано 15.05.2019 18:17 VladCore . Предыдущая версия .
Итог: Для O_DIRECT надо выравнивать адрес буфера тоже
От: VladCore  
Дата: 15.05.19 18:37
Оценка:
Отредактировано 16.05.2019 13:46 VladCore . Предыдущая версия . Еще …
Отредактировано 15.05.2019 19:39 VladCore . Предыдущая версия .
Отредактировано 15.05.2019 19:27 VladCore . Предыдущая версия .
Отредактировано 15.05.2019 18:38 VladCore . Предыдущая версия .
Ура! нашлось. Но не работает именно с O_DIRECT
От: VladCore  
Дата: 15.05.19 20:26
Оценка:
Здравствуйте, VladCore, Вы писали:


VC>Надо как то самому получить SafeFileHandle и передать его в констутор

VC>
VC>public FileStream(SafeFileHandle handle, FileAccess access, int bufferSize, bool isAsync);
VC>


Ура! нашёл. но с опцией O_DIRECT не работает. Кидает исключение ArgumentException в fileStream.Read(). Выравнивание я сделал как надо. Вот код который работает. но с закоментированным O_DIRECT. А мне именно для O_DIRECT как раз и надо!


FileStream OpenFileStreamWithoutCacheOnLinux(int bufferSize)
{
    var openFlags = /* Mono.Unix.Native.OpenFlags.O_DIRECT | */ Mono.Unix.Native.OpenFlags.O_RDONLY;
    int handle = Mono.Unix.Native.Syscall.open(TempFile, openFlags);
    IntPtr rawHandle = new IntPtr(handle);
    SafeFileHandle fh = new SafeFileHandle(rawHandle, false);
    FileStream fs = new FileStream(fh, FileAccess.Read, bufferSize, false);
    return fs;
}


тут bufferSize, размер и файла и в fileStream.Read() передается везде 8192 байт что бы выравнивание соблюсти.
Но увы. работает только если O_DIRECT закоментировать

Как заставить с O_DIRECT работать
Отредактировано 15.05.2019 20:28 VladCore . Предыдущая версия . Еще …
Отредактировано 15.05.2019 20:27 VladCore . Предыдущая версия .
Отредактировано 15.05.2019 20:27 VladCore . Предыдущая версия .
Re: Ура! нашлось. Но не работает именно с O_DIRECT
От: Sharowarsheg  
Дата: 16.05.19 07:47
Оценка:
Здравствуйте, VladCore, Вы писали:


VC>тут bufferSize, размер и файла и в fileStream.Read() передается везде 8192 байт что бы выравнивание соблюсти.


Выровняй на мегабайт, что будет?
Re[2]: Ура! нашлось. Но не работает именно с O_DIRECT
От: VladCore  
Дата: 16.05.19 10:21
Оценка:
Здравствуйте, Sharowarsheg, Вы писали:


VC>>тут bufferSize, размер и файла и в fileStream.Read() передается везде 8192 байт что бы выравнивание соблюсти.


S>Выровняй на мегабайт, что будет?


Попробовал. Тот же самый Invalid argument

Unhandled Exception: System.IO.IOException: Invalid argument
   at System.IO.FileStream.CheckFileCall(Int64 result, Boolean ignoreNotSupported)
   at System.IO.FileStream.ReadNative(Span`1 buffer)
   at System.IO.FileStream.ReadSpan(Span`1 destination)
   at System.IO.FileStream.Read(Byte[] array, Int32 offset, Int32 count)


O_DIRECT без выравнивания только на производительность влияет

почему у меня с именно O_DIRECT Exception вот в чем загадка

Повторюсь — без O_DIRECT xamarin-овский Mono.Unix.Native.Syscall.open прекрасно работает с microsoft-овским FileStream:


int bufferFile
string fileName;

var openFlags = /* Mono.Unix.Native.OpenFlags.O_DIRECT | */ Mono.Unix.Native.OpenFlags.O_RDONLY;
int handle = Mono.Unix.Native.Syscall.open(fileName, openFlags);
IntPtr rawHandle = new IntPtr(handle);
SafeFileHandle fh = new SafeFileHandle(rawHandle, false);
FileStream fs = new FileStream(fh, FileAccess.Read, bufferSize, false);
Re: Ура! нашлось. Но не работает именно с O_DIRECT
От: Cyberax Марс  
Дата: 16.05.19 22:23
Оценка:
Здравствуйте, VladCore, Вы писали:

VC>Ура! нашёл. но с опцией O_DIRECT не работает. Кидает исключение ArgumentException в fileStream.Read(). Выравнивание я сделал как надо. Вот код который работает. но с закоментированным O_DIRECT. А мне именно для O_DIRECT как раз и надо!

Выравнивать на страницу нужно положение буфера. Просто размер — не получится.
Sapienti sat!
Re[2]: Ура! нашлось. Но не работает именно с O_DIRECT
От: VladCore  
Дата: 17.05.19 13:45
Оценка: 4 (1)
Здравствуйте, Cyberax, Вы писали:

C>Здравствуйте, VladCore, Вы писали:


C>Выравнивать на страницу нужно положение буфера. Просто размер — не получится.


Я уже нашел и выше
Автор: VladCore
Дата: 15.05.19
написал про это. Кстати уже реализовал Вот бенчмарк с O_DIRECT вверху и внизу без с маленьким файлом который мог бы вместится в кеш:

Disk: /ssd, Size: 100M, Block: 4096 bytes
O_DIRECT is present
[Completed]  100.0% 00:00:08     12M/s Allocate
[Completed]  100.0% 00:00:02   37.8M/s Sequential read
[Completed]  100.0% 00:00:06   15.8M/s Sequential write
[Completed]  100.0% 00:00:20 6196.6K/s Random Read, 1 thread
[Completed]  100.0% 00:00:20 1252.4K/s Random Write, 1 thread
[Completed]  100.0% 00:00:20 6521.9K/s Random Read, 16 threads
[Completed]  100.2% 00:00:20 1306.7K/s Random Write, 16 threads


Disk: /ssd, Size: 100M, Block: 4096 bytes
O_DIRECT is disabled
[Completed]  100.0% 00:00:08   11.9M/s Allocate
[Completed]  100.0% 00:00:02   37.9M/s Sequential read
[Completed]  100.0% 00:00:04   16.6M/s Sequential write
[Completed]  100.0% 00:00:20  181.8M/s Random Read, 1 thread
[Completed]  100.0% 00:00:20 1448.9K/s Random Write, 1 thread
[Completed]  100.0% 00:00:20  769.3M/s Random Read, 16 threads
[Completed]  100.1% 00:00:20 1489.6K/s Random Write, 16 threads



Красота!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.