В документации к примечаниям CreateFile флаг FILE_FLAG_NO_BUFFERING требует, чтобы все операции ввода-вывода для дескриптора файла были кратны размеру сектора, а буферы ввода-вывода также были выровнены по адресам, кратным размеру сектора.
аюсь определить скорость диска в худшем случае, поэтому я написал следующую функцию.
static public decimal MBytesPerSec(string volume)
{
string filename = volume + "\\writetest.tmp";
if (System.IO.File.Exists(filename))
System.IO.File.Delete(filename);
System.IO.StreamWriter file = new System.IO.StreamWriter(filename);
char[] data = new char[64000];
Stopwatch watch = new Stopwatch();
watch.Start();
int i = 0;
for (; i < 1000; i++)
{
file.Write(data);
if (watch.ElapsedMilliseconds > 2000)
{
break;
}
}
watch.Stop();
file.Close();
System.IO.File.Delete(volume + "\\test.txt");
decimal mbytessec = (i * 64 / watch.ElapsedMilliseconds);
return mbytessec;
}
Функция работает нормально, но записи кэшируются, поэтому скорость не самая плохая.
В WIN32 C ++ я бы просто создал файл сFILE_FLAG_NO_BUFFERING
, FILE_FLAG_WRITE_THROUGH
опций, а затем убедитесь, что соблюдаете правила записи без кэширования (запись в файл со смещением размера сектора, с минимумом записи 4k)
Я нашел одинстатья в котором обсуждается техника .NET.
Поэтому я написал новую функцию (игнорируем математические ошибки).
static public decimal MBytesPerSecNonCached(string volume)
{
const FileOptions FILE_FLAG_NO_BUFFERING = (FileOptions)0x20000000;
string filename = volume + "\\writetest.tmp";
using (FileStream fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None, 1024, FileOptions.WriteThrough | FILE_FLAG_NO_BUFFERING))
{
byte[] data = new byte[65535];
int i = 0;
Stopwatch watch = new Stopwatch();
watch.Start();
for (; i < 1000; i++)
{
fs.Write(data, 0, 65535);
if (watch.ElapsedMilliseconds > 2000)
{
break;
}
}
watch.Stop();
fs.Close();
System.IO.File.Delete(filename);
decimal mbytessec = (i * 64 / watch.ElapsedMilliseconds);
return mbytessec;
}
}
Эта функция работает для размеров записи 4k, 16K и 32K, но как только я пытаюсь использовать размеры записи 64K, я получаю исключение:
Операция ввода-вывода не будет работать. Скорее всего, файл станет слишком длинным или дескриптор не был открыт для поддержки синхронных операций ввода-вывода.
Итак, как я могу это исправить, чтобы я мог тестировать с размерами записи больше 32 КБ (от 64 КБ до 4096 КБ)?