I've created the basis of a ray tracer, here's my testing function for drawing the scene:
public void Trace(int start, int jump, Sphere testSphere)
{
for (int x = start; x < scene.SceneWidth; x += jump)
{
for (int y = 0; y < scene.SceneHeight; y++)
{
Ray fired = Ray.FireThroughPixel(scene, x, y);
if (testSphere.Intersects(fired))
sceneRenderer.SetPixel(x, y, Color.Red);
else sceneRenderer.SetPixel(x, y, Color.Black);
}
}
}
SetPixel simply sets a value in a single dimensional array of colours. If I call the function normally by just directly calling it it runs at a constant 55fps. If I do:
Thread t1 = new Thread(() => Trace(0, 1, testSphere));
t1.Start();
t1.Join();
It runs at a constant 50fps which is fine and understandable, but when I do:
Thread t1 = new Thread(() => Trace(0, 2, testSphere));
Thread t2 = new Thread(() => Trace(1, 2, testSphere));
t1.Start();
t2.Start();
t1.Join();
t2.Join();
It runs all over the place, rapidly moving between 30-40 fps and sometimes going out of that range up to 50 or down to 20, it's not constant at all. Why is it running slower than it would if I ran the whole thing on a single thread? I'm running on a quad core i5 2500k.
This is difficult to answer without profiling your app, but I would suspect false sharing.
Both your threads are writing to a shared memory structure, which will cause your CPU caches to keep invalidating.
The easy way to test would be to create a separate output array for each thread.
It doesn't have to work - just look at the frame rates.
I wrote an article about this a while back: "Concurrency Hazards: False Sharing"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With