0

I'm attempting to marshal a forest of objects from C# .NET to native C++. That is: I have a graph of hundreds of millions of objects (if not more), that I wish to use in native C++. See it as a normal 'leaf'/'node' construction with pointers between leafs and nodes. I control both the C++ and the C# code, so I can make adjustments to the code.

The inner loop of the software is going to be implemented in native C++ for performance reasons. I basically want to tell the GC to stop for a while (to ensure objects aren't moved), then do the fancy C++ routine, and then continue the GC once it's done.

There are also things that I don't want to do:

  • Make my own mark & sweep algorithm to pin all objects in the graph. Not only will that be very time consuming, it'll also cost a lot of memory because I then have to keep track of all these GCHandle objects by myself.
  • Use native allocation methods like malloc. I've had a native C++ application in the past, and it suffered greatly from memory fragmentation, that .NET 'automatically' solves just fine... not to mention the benefit of GC.

So, any suggestions on how to do this?

atlaste
  • 30,418
  • 3
  • 57
  • 87
  • 1
    frankly, if I needed this (and note: C# performance is often not particularly different to C++, if you're doing things right) - I *think* I'd be looking at a different approach here - for example, manually allocating a buffer of unmanaged memory, and dealing with structs inside that space... then it isn't even touching GC in the first place. Viable? – Marc Gravell Dec 04 '14 at 11:04
  • Perhaps this article will help you http://stackoverflow.com/questions/6005865/prevent-net-garbage-collection-for-short-period-of-time – Alex Zhukovskiy Dec 04 '14 at 11:06
  • @MarcGravell That's pretty much the same as building my own small object allocator. Which is basically doing the same as the .NET GC. Let's call that 'Plan B' shall we :-) PS: .NET is over 10x slower than C++ in this particular case (yes that's been tested). – atlaste Dec 04 '14 at 11:28
  • @AlexJoukovsky I've noticed that article as well. It doesn't answer the question, since you have to be able to guarantee that objects aren't moved in order to use them in pinvoked code (which it doesn't). – atlaste Dec 04 '14 at 11:29
  • @atlaste i guess that it is impossible to fully stop GC, so i think it's the best you can do with. It seems better to move all interaction with graph into C++ library and interact only with small pieces of data, not pass entire graph from C# app and back after processing – Alex Zhukovskiy Dec 04 '14 at 11:33
  • @AlexJoukovsky I found that the funny thing with "impossible" is that there is usually someone answering questions on StackOverflow that knows a workaround. – atlaste Dec 04 '14 at 12:01
  • @atlaste I hope you'l find an answer, but I think this idea is not allowed by CLR design – Alex Zhukovskiy Dec 04 '14 at 12:04
  • 1
    "C# is slower" is a non sequiter. You mean that your C# code is slower. – David Heffernan Dec 04 '14 at 19:20
  • @DavidHeffernan I didn't say that, and I really, really, really don't want to begin a C# versus C++ performance war here. If it makes you feel better, let's simply assume that I have a good reason and "simply" want to interop with a gazillion .NET objects, preferably without writing my own memory manager, GC or whatever great things .NET already has to offer. Question is: how to do that? – atlaste Dec 05 '14 at 10:50

1 Answers1

1

I will look at using managed C++.

  • Maybe accessing the .NET objects from manage C++ will be fast enough.
  • Otherwise use managed C++ to “walk” the .net objects and create native C++ objects, delete them all once done.
  • Or create a class factory class in manage C++ that can be used to create the C++ object being callable from C#, once again delete them all once done.
  • Or do as Marc Gravel says and manually allocating a buffer of unmanaged memory, and dealing with structs inside that space, maybe using a code generator driven from attributes on your C# classes.
Ian Ringrose
  • 51,220
  • 55
  • 213
  • 317
  • Hmm come to think of it... actually something like that might be interesting: I hadn't thought of using managed C++ yet. Good idea; perhaps in combination with `IDisposable`, `Reflection.Emit` and some other alloc/dealloc methods that might just do the trick. Good idea, thanks, I'll pursue this line of thought. – atlaste Jan 05 '15 at 13:16