Re[2]: Ура! нашлось. Но не работает именно с O_DIRECT
Здравствуйте, 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
Красота!
[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
Итог: Для O_DIRECT надо выравнивать адрес буфера тоже
От:
VladCore
Дата: 15.05.19 18:37
Оценка:
Ура! нашлось. Но не работает именно с 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 работать
Re: Ура! нашлось. Но не работает именно с O_DIRECT
Здравствуйте, 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!
Пока на собственное сообщение не было ответов, его можно удалить.
Удалить