Ray Tracing with Cilk Plus

Ray Tracing with Cilk Plus


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?

Downloadtext/x-c++src ray.cpp3.9 KB
6 posts / novo 0
Último post
Para obter mais informações sobre otimizações de compiladores, consulte Aviso sobre otimizações.

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


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?

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


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


Downloadimage/png 2013-07-16-162422.png16.7 KB

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:

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 << "P5n" << n << " " << n << "n255n";
    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;

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

Deixar um comentário

Faça login para adicionar um comentário. Não é membro? Inscreva-se hoje mesmo!