The Code

To meet space constraints, we’ve published a complete standalone version of the program that actually uses delay loops to simulate being in the ODE package itself. This means that all the code listed strictly concerns the code that was written to introduce threading (two different ways) via Threading Building Blocks (see Example 11-62 and Example 11-63). This model program contains none of the ODE but behaves like the ODE at a high level. The timing delays in the listing simulate the effects of the real calls in the ODE such that the speedup results seem consistent with the trials we ran. The web site for this book has instructions on how to download a modified ODE as well, which actually incorporates these changes into the whole ODE.

Example 11-62. ODE: includes and delay placeholders

#include <stdio.h>
#include <vector>
#include <windows.h>
#include "tbb	ask_scheduler_init.h"
#include "tbb	ask.h"
#include "tbbparallel_for.h"
#include "tbblocked_range.h"
#include "tbb	ick_count.h"

typedef int object_t;
typedef std::vector<object_t*> world_t;
typedef std::vector<object_t*> island_t;
typedef std::vector<island_t*> islands_vector;

const unsigned int N  = 20000; // Weight of the computation complexity

const int grain_size  = 5; // Grainsize for parallel_for: hard to
                           // find a good number if the
                           // environment changes dynamically

const int step_time   = 1; // Time to spend processing one object
                           // in dInternalStepIslandFast (solver)

const int search_time = 1; // Time to spend processing one object
                           // in processIslandsFast (islands finder)

void busy (int weight)
{
    for (int i = 0; i < weight; i++) {
        static volatile int x;
        for (int j = 0; j < N; j++)
            ++x;
    }
}

// Simulates solver
void dInternalStepIslandFast (int obj_num, island_t& island)
{

   for (int i = 0; i < obj_num; i++)
       busy (step_time);
}

// put Example 11-57 through Example 11-61 here //

Example 11-63. ODE: set-up

// after Example 11-62, and Example 11-57 through Example 11-61

void main (int argc, char **argv)
{
    unsigned int world_size = 400;
    int tbb_num_threads = tbb::task_scheduler_init::automatic;

    // Process program input arguments
    unsigned int num = 0;
    for (int i=1; i<argc; i++)
    {
        if (_stricmp(argv[i],"-numThreads")==0) {
            if ((i < argc-1) && ((num = atoi(argv[i+1])) > 0))
                tbb_num_threads = num;
        }
        else if (_stricmp(argv[i],"-numObjects")==0) {
            if ((i < argc-1) && ((num = atoi(argv[i+1])) > 1))
                world_size = num;
        }
    }

    // Initialize the world with objects
    world_t world(world_size);

    if (tbb_num_threads != tbb::task_scheduler_init::automatic)
        printf ("Number of threads: %d
", tbb_num_threads);
    else
        printf ("Running default number of threads
");

    printf ("Number of objects in the scene: %d
", world_size);

    //**** Serial version:
    tbb::tick_count t1_serial = tbb::tick_count::now( );

    // Frame loop: simulates dynamically changing environment:
    // total number of objects is constant, number of islands varies
    for (unsigned int i = 1; i <= world_size/2; ++i)
        processIslandsFast (i, world);

    tbb::tick_count t2_serial = tbb::tick_count::now( );
    printf ("Serial time: %g seconds
",
            (t2_serial-t1_serial).seconds ( ));

    //**** tbb::parallel_for version
    tbb::task_scheduler_init tbb_init(tbb_num_threads);
    tbb::tick_count t1_pfor = tbb::tick_count::now( );

    // Frame loop:
    for (unsigned int i = 1; i <= world_size/2; ++i)
        processIslandsFastPfor (i, world);

    tbb::tick_count t2_pfor = tbb::tick_count::now( );
    printf ("parallel_for version time: %g seconds
",
                  (t2_pfor-t1_pfor).seconds ( ));

    //**** tbb::task version:
    tbb::tick_count t1_task = tbb::tick_count::now( );

    // Frame loop:
    for (unsigned int i = 1; i <= world_size/2; ++i)
    {
        tbb::task& root =
              *new (tbb::task::allocate_root( ))
                 process_world (i, world);
        root.set_ref_count (1);
        tbb::task::spawn_root_and_wait (root);
    }

    tbb::tick_count t2_task = tbb::tick_count::now( );
    printf ("Task version time: %g seconds
",
                  (t2_task-t1_task).seconds ( ));

}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.121.214