Как да използвате x64 Interlocked Operations срещу MemoryMappedFiles в .net

Трябва да използвам взаимосвързани операции (CompareExchange, Increment и т.н.) срещу памет в MemoryMappedFiles в .NET.

Намерих този отговор на много подобен въпрос. Проблемът е, че Interlocked Operations не се експортират от kernel32 (или друга) dll на 64-битова ОС (вижте напр. http://blog.kalmbachnet.de/?postid=46).

Има ли друг начин как мога да извикам Interlocked функции на блок памет в 64-битов .NET процес?


person Jan    schedule 23.09.2014    source източник
comment
Бих се опитал да напиша моя собствена C Dll с експортирани функции, извикващи взаимосвързани функции, и PInvoke от .NET.   -  person Alex F    schedule 23.09.2014
comment
@AlexFarber Отлична точка! Тъкмо исках да попитам за това:) Случайно знаете ли дали мога лесно да намеря ASM имплементацията на присъщи за компилатор Interlocked функции (напр. http://msdn.microsoft.com/en-us/library)/2ddez55b(v=vs.80).aspx) ? За да не се налага сам да преоткривам ASM кода   -  person Jan    schedule 23.09.2014
comment
Не е нужно да правите това, просто извикайте необходимите функции от родния Dll, компилаторът ще свърши останалото. Искам да кажа, че за всяка взаимосвързана функция, от която се нуждаете, напишете експортирана Dll функция, която извиква взаимосвързана функция.   -  person Alex F    schedule 23.09.2014
comment
Смисълът на използването на този вид функция за атомен достъп е да бъде вградена, така че да има абсолютно минимални разходи. След като трябва да pinvoke, тогава тази точка се губи напълно, просто няма смисъл да избягвате именуван обект за синхронизиране.   -  person Hans Passant    schedule 23.09.2014
comment
@HansPassant В моя случай споделям буфер на паметта със стотици дълги стойности. Ще имам нужда от стотици синхронизиращи обекти (мутекс и т.н.), за да избегна спорове. Също така се надявах на Interlocked, тъй като те принуждават да прокарат новата стойност през линиите на кеша на паметта (за разлика от бариерите на паметта, които имат неспецифично време) - но сте прав, че P/Invokes вероятно напълно ще срине това предимство :|   -  person Jan    schedule 23.09.2014


Отговори (1)


Напишете сами малка C++/CLI помощна библиотека, която предоставя взаимосвързани операции, използвани от управляван код.

Вярвам, че най-бързият път за взаимодействие би бил да се изложи управляван клас, който вътрешно извиква неуправляема функция, която сама по себе си използва взаимосвързаните вътрешни елементи. По този начин дори не е нужно да преминавате през PInvoke.

person usr    schedule 16.10.2014
comment
За съжаление това не е вярно - C++/CLI е по-бавен от P/Invoke с потиснати проверки - вижте напр. тук: codeproject.com/Articles/253444/ или тук: xinterop. com/index.php/2013/05/01/ Така че P/Invoke е правилният начин (за съжаление той все още рекламира дузина инструкции за всяко повикване) - person Jan; 04.11.2014
comment
Първата статия изглежда показва, че обвивката на C++ е по-бърза. Във втората статия обвивката на C++ е толкова по-бавна, че започвам да се съмнявам. Може би оптимизациите не са били включени или е извършена допълнителна работа (наистина - C++ обвивката извиква sqrt само чрез междинен клас. защо?). И в двете статии времената за бенчмарк бяха много малки. Много шум. DateTime.Now също не е много точен. Обикновено се увеличава на стъпки от 15 ms. Неговите тестове бяха в диапазона 10-30ms. Не се доверявам на нито една статия и няма да инвестирам време, за да проучвам повече. - person usr; 04.11.2014
comment
Съгласен съм с вашите констатации. Основната точка е, че ако искате максимална скорост, трябва да надстроите всички сондирания за проследяване на стека и т.н., свързани с управлявани‹-›родни преходи. с P/Invokes можете да направите това, като посочите SuppressUnmanagedCodeSecurity атрибут. С обвивката на C++/CLI получавате всички тези проверки по подразбиране и доколкото ми е известно, не можете да ги използвате за пряк път. - person Jan; 04.11.2014