3F / DllExport

.NET DllExport with .NET Core support (aka 3F/DllExport aka DllExport.bat)
MIT License
960 stars 133 forks source link

Perfomance degradation in multi thread #217

Open schadin opened 1 year ago

schadin commented 1 year ago

Hi. I'm development of dll export data to kafka. Library is a plugin for other windows native application. I'm exported method from my dll by Dllexport. All operations available by way of one Core class. Exported methods call method of Core class. Dll has two mode of work:

For test i wrote two applications: native and .net. Native call dll by exported method, .net by Core class. In Stub mode throughput - 100-120k per second in both applications. In Kafka mode and single threaded both application ~10k per second. In Kafka mode and multi threaded .net application have throughput 50-55k per second. But native application - 30k per second.

How can I find out the reasons for the degradation on performance with call through exported methods?

Thank you.

3F commented 1 year ago

Hello,

If I understood correctly, the problem may be related to the way the both processes interop using p/invoke. This may affect performance (of course) same as here: https://github.com/KirillOsenkov/Benchmarks/pull/5#issuecomment-832017735

Try to reduce frequent interruption via fragmented sending of data with caching

Or look at calling your code, Maybe there are some marshaling issue and so on. https://github.com/3F/DllExport/wiki/Quick-start#about-data-types

Try profiling and make sure you don't have the debug config anywhere

On 20.01.2023 12:06, Alexey Schadin wrote:

Message ID: @.***>

schadin commented 1 year ago

Hello, If I understood correctly, the problem may be related to the way the both processes interop using p/invoke. This may affect performance (of course) same as here: KirillOsenkov/Benchmarks#5 (comment) Try to reduce frequent interruption via fragmented sending of data with caching Or look at calling your code, Maybe there are some marshaling issue and so on. https://github.com/3F/DllExport/wiki/Quick-start#about-data-types Try profiling and make sure you don't have the debug config anywhere On 20.01.2023 12:06, Alexey Schadin wrote: Message ID: @.***>

Thank you for reply. I've rewritting multithread from ThreadPool to TPL DataFlow, it increase throughput library. If not send data to Kafka throughput is 100k-150k messages per seconds. If send data to Kafka throughput data flow from exported method (35k) lower then .net application(80k). I'am tested variant with when .NET applicaiton load dll from P/Invoke, throughput equals native application (35k). My coworker think that exported methods limitation threads perfomance. I can't accept or reject it.

I don't know the possible solution. And I'm not sure which way to go.

3F commented 1 year ago

> If send ... from exported method (35k) and > when .NET applicaiton load dll from P/Invoke, ... (35k)

Which side is the host application for both cases? Yet again looks related to the p/invoke use, because CLR internally binds addresses between VT & EAT and operates with the heap using marshalling almost the same to the dllimport as far as I remember it.

This is what I'm talking about, Interruptions are totally expensive for both sides. Conari, for example, can even limit the number of address bindings and its signature predefinition in attempt to process only actual data at the top of the stack https://github.com/3F/Conari/blob/master/Conari/Core/Provider.cs#L338-L391 It helped to be a bit faster even than the internal implementation as noticed in PR above.

Thus, first of all, how many actual calls through p/invoke in your 35k ?

On 26.01.2023 17:39, Alexey Schadin wrote:

Hello, If I understood correctly, the problem may be related to
the way the both processes interop using p/invoke. This may affect
performance (of course) same as here: KirillOsenkov/Benchmarks#5
(comment)
<https://github.com/KirillOsenkov/Benchmarks/pull/5#issuecomment-832017735>
Try to reduce frequent interruption via fragmented sending of data
with caching Or look at calling your code, Maybe there are some
marshaling issue and so on.
https://github.com/3F/DllExport/wiki/Quick-start#about-data-types
Try profiling and make sure you don't have the debug config anywhere
… <#>
On 20.01.2023 12:06, Alexey Schadin wrote: Message ID: /*@*/.***

Thank you for reply. I've rewritting multithread from ThreadPool to TPL DataFlow, it increase throughput library. If not send data to Kafka throughput is 100k-150k messages per seconds. If send data to Kafka throughput data flow from exported method (35k) lower then .net application(80k). I'am tested variant with when .NET applicaiton load dll from P/Invoke, throughput equals native application (35k). My coworker think that exported methods limitation threads perfomance. I can't accept or reject it.

I don't know the possible solution. And I'm not sure which way to go.

Message ID: @.***>