2014-09-23 11 views
7

Devo utilizzare le operazioni interbloccate (CompareExchange, Increment ecc.) Nella memoria in MemoryMappedFile s in .NET.Come utilizzare le operazioni interbloccate x64 contro MemoryMappedFiles in .net

Ho trovato questo answer a una domanda molto simile. Il problema è che le operazioni interbloccate non vengono esportate da dll kernel32 (o qualsiasi altra) su OS a 64 bit (vedere ad esempio http://blog.kalmbachnet.de/?postid=46).

C'è un altro modo in cui posso chiamare le funzioni interbloccate su un blocco di memoria in un processo .NET a 64 bit?

+1

Proverei a scrivere il mio C Dll con funzioni esportate che chiamano funzioni interbloccate e PInvoke da .NET. –

+0

@AlexFarber Punto eccellente! Stavo solo andando a chiedere informazioni su questo :) Ti capita di sapere se posso facilmente scoprire l'implementazione ASM delle funzioni intrinseche interbloccate del compilatore (ad esempio [http://msdn.microsoft.com/en-us/library/2ddez55b(v = vs.80) aspx] (http://msdn.microsoft.com/en-us/library/2ddez55b (v = vs.80) aspx))? In modo che non debba reinventare il codice ASM me stesso – Jan

+2

Non è necessario farlo, basta chiamare le funzioni richieste dalla DLL nativa, il compilatore farà il resto. Voglio dire, per ogni funzione interbloccata di cui hai bisogno, scrivi la funzione Dll esportata che chiama la funzione Interlocked. –

risposta

1

Scriviti una piccola libreria di helper C++/CLI che fornisce operazioni interbloccate che possono essere consumate dal codice gestito.

Credo che il percorso di interoperabilità più veloce sarebbe quello di esporre una classe gestita che chiama internamente in una funzione non gestita che a sua volta fa uso degli intrinseci interbloccati. In questo modo non devi nemmeno passare attraverso PInvoke.

+0

Sfortunatamente questo non è vero - C++/CLI è più lento di P/Invoke con controlli soppressi - vedi ad es. qui: http://www.codeproject.com/Articles/253444/PInvoke-Performance?msg=4551831#xx4551831xx o qui: http://www.xinterop.com/index.php/2013/05/01/ccli- vs-pinvoke-performance-part-one/ Quindi P/Invoke è la strada da percorrere (sfortunatamente si pubblicano ancora una dozzina di istruzioni per ogni chiamata) – Jan

+0

Il primo articolo sembra mostrare che il wrapper C++ è più veloce. Nel secondo articolo, il wrapper C++ è molto più lento che inizio a diventare sospetto. Forse le ottimizzazioni non sono state attivate o è stato eseguito un lavoro extra (infatti - il wrapper C++ chiama sqrt solo attraverso una classe intermedia. Perché?). In entrambi gli articoli i tempi di riferimento erano molto piccoli. Molto rumore. DateTime.Now non è molto preciso neanche. Normalmente, aumenta in passi di 15ms. I suoi test erano nella gamma 10-30ms. Non mi fido di nessuno dei due articoli e non investirò il tempo per investigare di più. – usr

+0

Sono d'accordo con le tue scoperte. Il punto principale è che se si desidera la massima velocità è necessario superare tutte le rilevazioni di stack trace ecc. Associate alle transizioni native gestite da <->. con P/Invokes puoi farlo specificando l'attributo SuppressUnmanagedCodeSecurity. Con il wrapper C++/CLI si ottengono tutti quei controlli di default e, a mia conoscenza, non è possibile collegarli. – Jan

Problemi correlati