В настоящее время я использую общую память с двумя сопоставленными файлами (1,9 ГБ для первого и 600 Мбайт для второго) в программном обеспечении.
Я использую процесс, который считывает данные из первого файла, обрабатывает данные и записывает результаты во второй файл.
Иногда я замечал сильную задержку (причина не в моих силах) при чтении или записи в виде отображения с функцией memcpy.
Время доступа к общей памяти Windows медленное
отображенные файлы создаются таким образом:
m_hFile = ::CreateFileW(SensorFileName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
m_hMappedFile = CreateFileMapping(m_hFile,
NULL,
PAGE_READWRITE,
dwFileMapSizeHigh,
dwFileMapSizeLow,
NULL);
И память отображение осуществляется таким образом:
m_lpMapView = MapViewOfFile(m_hMappedFile,
FILE_MAP_ALL_ACCESS,
dwOffsetHigh,
dwOffsetLow,
m_i64ViewSize);
The dwOffsetHigh/dwOffsetLow являются "соответствие" зернистость от информации о системе.
Процесс считывает около 300 КБ * N раз, сохраняя это в буфере, обрабатывая и затем записывая 300 Кбайт * N раз обрабатываемое содержимое предыдущего буфера во второй файл.
У меня есть два разных вида памяти (созданные/перемещенные с помощью функции MapViewOfFile) размером 10 МБ в качестве размера по умолчанию.
Для размера памяти, я тестировал 10kBytes, 100kB, 1MB, 10MB и 100MB.
Статистически нет разницы, 80% времени, как описано ниже (~ 200 мс), но процесс записи очень медленный.
Обычно:
1/Чтение выполняется в ~ 200 мс.
2/Процесс выполняется за 2,9 секунды.
3/Запись выполняется в ~ 200 мс.
Я вижу, что 80% времени, как чтение, так и запись (в худшем случае оба медленные), займет от 2 до 10 секунд.
Пример: Для записи, я использую ниже код
for (unsigned int i = 0 ; i < N ; i++) // N = 500~3k
{
// Check the position of the memory view for ponderation
if (###)
MoveView(iOffset);
if (m_lpMapView)
{
memcpy((BYTE*)m_lpMapView + iOffset, pANNHeader, uiANNStatus);
// uiSize = ~300 kBytes
memcpy((BYTE*)m_lpMapView + iTemp, pLine[i], uiSize);
}
else
return uiANNStatus;
}
После использования функции GetTickCount, чтобы точно определить, где задержка, я вижу, что второй тетсру вызов всегда один принимает большую часть времени ,
Итак, до сих пор я вижу N (для теста, я использовал N = 500) звонки на memcpy, принимающие 10 секунд в худшее время при использовании этих общих воспоминаний.
Я сделал временное программное обеспечение, которое выполняло то же количество вызовов memcpy, столько же данных и не могло видеть проблему.
Для тестов я использовал следующие условия, все они показывают ту же задержку:
1/Я могу видеть это на различных компьютерах, 32 или 64 бита из окна 7 к окнам 10.
2/с использованием основной поток или многопоточность (до 8 с критическими разделами для синхронизации) для чтения/записи.
3/ОС на SATA или SSD, память отображает файлы программного обеспечения физически на жестком диске SATA или SSD, а на внешнем жестком диске тесты выполняются через USB1, USB2 или USB3.
Прошу вас, как вы думаете, моя ошибка в том, что memcpy идет медленно.
С уважением.
Это нормально с картографическими файлами памяти. В какой-то момент ему необходимо физически передать данные на диски - и ваши диски связаны с IO. – SergeyA
Возможно, вам понадобится профиль для изменения кода, где вы буферизируете данные и не используете файлы с отображением памяти. Измените размер буфера, чем размер входного блока, чтобы повысить производительность. –
Поиск на сайте MSDN для API, который может заблокировать вашу память, чтобы предотвратить замену ОС на жесткий диск. –