Низкая производительность разделяемой памяти при переходе на 64-битную ОС

У меня проблема с 32-битным устаревшим приложением, работающим в 64-битных окнах. Рассматриваемое приложение использует CreateFileMapping для создания общей памяти. Когда это выполняется в 64-битной Windows, любая попытка доступа к этой общей памяти из другого процесса занимает около 1 секунды. Общая память создается с помощью флагов защиты страницы:

flProtect = PAGE_READONLY | SEC_NOCACHE | SEC_COMMIT;

когда та же память создается с использованием:

flProtect = PAGE_READONLY | SEC_COMMIT;

проблема исчезает. На данный момент этот обходной путь приемлем, но у нас есть некоторые устройства, требующие установки флага SEC_NOCACHE.

Может ли кто-нибудь просветить меня, почему SEC_NOCACHE повлияет на производительность в этой ситуации?

Обновление: кажется, что только запись в этот буфер увеличилась до 1000 мс. На чтение вроде не влияет. За это время мы записываем в буфер около 5 МБ.

Update2: это программное обеспечение используется во многих системах, и в одной из систем есть физическое устройство, требующее использования этих флагов. В настоящее время мы ограничены запуском машины с этим устройством в 32-битных окнах.


person Justin    schedule 03.09.2010    source источник
comment
SEC_NOCACHE: Приложения не должны использовать этот атрибут, за исключением случаев, когда это явно требуется для устройства. Есть ли причина, по которой вы используете этот флаг? Вы (или первоначальный разработчик) просто неверно истолковали его цель?   -  person peterchen    schedule 04.09.2010
comment
У нас есть устройство, которое требует установки этого флага.   -  person Justin    schedule 08.09.2010


Ответы (3)


Вы отключаете кэш файловой системы с помощью этого флага. Да, это огромная разница, она заставляет ОС работать с драйвером диска и напрямую читать сектора. Цилиндры нельзя читать и кэшировать, что отключает оптимизацию, которая делает чтение дорожек без необходимости перемещать считывающую головку так дешево. И ленивая обратная запись отключена, оптимизация, которая делает запись на диск мгновенной.

person Hans Passant    schedule 03.09.2010
comment
Это файл с отображением памяти, доступ к жесткому диску не требуется. - person Justin; 03.09.2010
comment
Есть. Если вы укажете INVALID_HANDLE_VALUE для аргумента hFile CreateFileMapping, то он будет резервироваться файлом подкачки. Проверьте документы SDK. - person Hans Passant; 03.09.2010
comment
Почему это изменило производительность записи с 32 до 64 бит. Если бы это было большой проблемой, разве я не увидел бы снижение производительности и в 32-битной версии? - person Justin; 08.09.2010
comment
32-битный код работает на уровне эмуляции под названием Wow64. Подробности реализации очень найти сложно, это нигде не задокументировано. Я подозреваю, что 64-разрядным драйверам нужно прыгать через обручи, чтобы иметь дело со страницами, которые были выделены на уровне эмуляции. - person Hans Passant; 08.09.2010
comment
Я выбрал это в качестве ответа, потому что считаю, что проблема в слое wow64. - person Justin; 10.09.2010

Вот что говорит Microsoft об этом флаге:

Флаг SEC_NOCACHE предназначен для архитектур, требующих размещения в памяти различных блокирующих структур, которые никогда не загружаются в кэш ЦП. На машинах x86 и MIPS использование этого флага просто снижает производительность, поскольку аппаратное обеспечение обеспечивает согласованность кеша.

К сожалению, они не определяют количество замедления.

person Mark Ransom    schedule 03.09.2010
comment
Это правда, однако в 32-битной системе это замедление составляет менее 10 мс. В 64 она находится в пределах 1000мс. - person Justin; 03.09.2010
comment
@Justin: оба процесса 32-битные? По крайней мере, на *NIX существует аналогичная ситуация с общей памятью, созданной 32-битным процессом, доступ к которой осуществляется из 64-битного процесса и наоборот. И, кстати, если в цитируемой статье есть хоть какая-то правда, то отбросьте флаг: все многопроцессорные/ядерные системы, которые сейчас запускает Windows, явно когерентны с кэшем (в отличие от первых SMP-систем более десяти лет назад, на которых работала WinNT 3.5). - person Dummy00001; 04.09.2010
comment
@Dummy: оба процесса 32-битные. Спасибо за многоядерный пункт, я посмотрю на это. Мы используем только одно оборудование, которое нуждается в этом флаге, и оно используется в 32-битной системе. В настоящее время мы проверяем, является ли ОС 32 или 64, и устанавливаем флаги. Мне просто интересно узнать причину этого замедления. - person Justin; 04.09.2010

Я предполагаю, что, поскольку память должна быть переназначена с 64-битной на 32-битную, предоставление буфера «отскока» становится дорогим. Когда кэширование включено, этот буфер отказов является неявным, и ОС может обойти необходимость постоянного обновления раздела памяти.

person Christopher    schedule 03.09.2010
comment
Это то, к чему я склоняюсь, но 1000 мс кажутся запредельным временем для этих операций. - person Justin; 03.09.2010
comment
Буферы отказов нужны только для оборудования DMA, которому нужен 32-битный физический адрес. В 32-битных приложениях в пользовательском режиме преобразование выполняется MMU, и любой адрес в памяти, даже больше 4 ГБ, может быть сопоставлен с 32-битным виртуальным адресом. - person Ben Voigt; 04.09.2010
comment
@ben: даже без буферов отскока может ли отображение с 64 на 32 бит добавить такие накладные расходы? - person Justin; 04.09.2010
comment
Нет, MMU точно так же используется в 32-битной ОС. - person Ben Voigt; 04.09.2010