Software Archive
Read-only legacy content
17061 Discussions

Ray Tracing with Cilk Plus

Julio_V_
Beginner
1,194 Views

Hi,

I'm trying to parallelize a Ray Tracing code that I've found here (in C++): http://www.ffconsultancy.com/languages/ray_tracer/comparison.html.

I'm using Visual Studio 2012 + Intel C++ Composer XE. To run de executable, what I'm doing is to build with VS 2012, and run with cmd like this:

cd "path to the debug folder"

ray.exe 1 > fig.ppm

The number 1 is the level of complexitity of the image, being 1 the lighter to be done, and "> fig.ppm" exports de results to a .ppm image. The program results in a sphere (level 1) or many spheres.

The problem is, when I try to change de code to use Cilk, the results are wrong. Instead of showing the normal result for level 1, the image is completely messed up. I've tried to:

  1. Change the two firsts "for" in the main to cilk_for (one at the time and both at the same time);
  2. While doing the #1, tried to add cilk_spawn before function calling;
  3. While doing #1 and #2, tried to add cilk_sync after the fourth "for".

All these attempts have resulted in wrong outputs.

Can someone help me with this? Where should I add cilk_for, cilk_spawn and/or cilk_sync for this to work?

0 Kudos
5 Replies
Barry_T_Intel
Employee
1,194 Views

While I haven't looked at your code yet, my instinctive reaction is you've got a race.  To prove it, run with a single worker.  If the image is correct, you need to find it and fix it.

The Cilkscreen race detector is a free download which will watch the executing code and tell you about races in any possible schedule of the executed code.  It's available as part of the Intel Cilk Plus SDK at http://cilkplus.org/download .

    - Barry

0 Kudos
Julio_V_
Beginner
1,194 Views

Hi,

I've read about Cilkscreen, but I haven't founded how to run it with my executable. I've tried te type: cilkscreen -- ray.exe 1 > fig.ppm, but it doesn't recognize the cilkscreen command.

How can I run it in command prompt?

0 Kudos
Barry_T_Intel
Employee
1,194 Views

The Cilkscreen race detector is part of the "Intel Cilk Plus SDK" which is a free download from the cilkplus.org website:  http://cilkplus.org/download .  The SDK also includes the Cilkview scalability analyzer.  Documentation on them is included in the download.

   - Barry

0 Kudos
Julio_V_
Beginner
1,194 Views

Hi,

I was able to install and run cilkscreen, but when I do, the executable stops working (image attached)

0 Kudos
Barry_T_Intel
Employee
1,194 Views

I do not have anything that views a ppm image, so I can't view the images produced by this.  Which makes working with it difficult.

However, it's pretty obvious that you've got races.  Consider your main loop:

[cpp]

int main(int argc, char *argv[]) {
    int level = 6, n = 512, ss = 4;
    if (argc == 2) level = atoi(argv[1]);
    Vec light = unitise(Vec(-1, -3, 2));
    Scene *s(create(level, Vec(0, -1, 0), 1));
    cout << "P5\n" << n << " " << n << "\n255\n";
    for (int y=n-1; y>=0; --y)
        for (int x=0; x<n; ++x) {
            double g=0;
            for (int dx=0; dx<ss; ++dx)
                for (int dy=0; dy<ss; ++dy) {
                    Vec dir(unitise(Vec(x+dx*1./ss-n/2., y+dy*1./ss-n/2., n)));
                    g += ray_trace(light, Ray(Vec(0, 0, -4), dir), *s);
                }
                cout << char(int(.5 + 255. * g / (ss*ss)));
        }
    delete s;
    return 0;
}

[/cpp]

Now consider making the loop over "dx" a cilk_for.  You'll be racing on the calculation of "g," which would be bad.

Now consider moving the cilk_for out to the loop over "x." You've removed the race on "g" (since it's now a local inside the loop), but now you're racing on the output.  You'd need to buffer the row of information in memory and write it out at the completion of the loop over "x."  Be warned that if you use a simple array to hold the values, you risk performance problems due to false sharing as the threads write to adjacent elements of the array.

    - Barry

0 Kudos
Reply