Note that there are some explanatory texts on larger screens.

plurals
  1. POWriting performance critical C# code in C++
    primarykey
    data
    text
    <p>I'm currently working on some performance critical code, and I have a particular situation where I'd love to write the whole application in C#, but performance reasons mean C++ ends up being FAR faster. </p> <p>I did some benchmarking on two different implementations of some code (One in C#, another in C++) and the timings showed that the C++ version was 8 times faster, both versions in release mode and with all optimizations enabled. (Actually, the C# had the advantage of being compiled as 64-bit. I forgot to enable this in the C++ timing)</p> <p>So I figure, I can write the majority of the code base in C# (Which C# makes very easy to write), and then write native versions of things where the performance is critical. The particular code piece I tested in C# and C++ was one of the critical areas where > 95% of processing time was spent.</p> <p>What's the recommended wisdom on writing native code here though? I've never written a C# application that calls native C++, so I have no idea what to do. I want to do this in a way that minimizes the cost of having to do the native calls as much as possible.</p> <p>Thanks!</p> <p>Edit: Below is most of the code that I'm actually trying to work on. It's for a n-body simulation. 95-99% of the CPU time will be spent in Body.Pairwise().</p> <pre><code>class Body { public double Mass; public Vector Position; public Vector Velocity; public Vector Acceleration; // snip public void Pairwise(Body b) { Vector dr = b.Position - this.Position; double r2 = dr.LengthSq(); double r3i = 1 / (r2 * Math.Sqrt(r2)); Vector da = r3i * dr; this.Acceleration += (b.Mass * da); b.Acceleration -= (this.Mass * da); } public void Predict(double dt) { Velocity += (0.5 * dt) * Acceleration; Position += dt * Velocity; } public void Correct(double dt) { Velocity += (0.5 * dt) * Acceleration; Acceleration.Clear(); } } </code></pre> <p>I also have a class that just drives the simulation with the following methods:</p> <pre><code> public static void Pairwise(Body[] b, int n) { for (int i = 0; i &lt; n; i++) for (int j = i + 1; j &lt; n; j++) b[i].Pairwise(b[j]); } public static void Predict(Body[] b, int n, double dt) { for (int i = 0; i &lt; n; i++) b[i].Predict(dt); } public static void Correct(Body[] b, int n, double dt) { for (int i = 0; i &lt; n; i++) b[i].Correct(dt); } </code></pre> <p>The main loop looks just like:</p> <pre><code>for (int s = 0; s &lt; steps; s++) { Predict(bodies, n, dt); Pairwise(bodies, n); Correct(bodies, n, dt); } </code></pre> <p>The above is just the bare minimum of a larger application I'm actually working on. There's some more things going on, but the most performance critical things occur in these three functions. I know the pairwise function is slow (It's n^2), and I do have other methods that are faster (Barnes-hutt for one, which is n log n) but that's beyond the scope of what I'm asking for in this question.</p> <p>The C++ code is nearly identical:</p> <pre><code>struct Body { public: double Mass; Vector Position; Vector Velocity; Vector Acceleration; void Pairwise(Body &amp;b) { Vector dr = b.Position - this-&gt;Position; double r2 = dr.LengthSq(); double r3i = 1 / (r2 * sqrt(r2)); Vector da = r3i * dr; this-&gt;Acceleration += (b.Mass * da); b.Acceleration -= (this-&gt;Mass * da); } void Predict(double dt) { Velocity += (0.5 * dt) * Acceleration; Position += dt * Velocity; } void Correct(double dt) { Velocity += (0.5 * dt) * Acceleration; Acceleration.Clear(); } }; void Pairwise(Body *b, int n) { for (int i = 0; i &lt; n; i++) for (int j = i + 1; j &lt; n; j++) b[i].Pairwise(b[j]); } void Predict(Body *b, int n, double dt) { for (int i = 0; i &lt; n; i++) b[i].Predict(dt); } void Correct(Body *b, int n, double dt) { for (int i = 0; i &lt; n; i++) b[i].Correct(dt); } </code></pre> <p>Main loop:</p> <pre><code>for (int s = 0; s &lt; steps; s++) { Predict(bodies, n, dt); Pairwise(bodies, n); Correct(bodies, n, dt); } </code></pre> <p>There also exists a Vector class, that works just like a regular mathematical vector, which I'm not including for brevity.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload