[Bf-taskforce25] Is there a parallel pipeline in blender?

Ruan Beihong ruanbeihong at gmail.com
Wed Aug 5 11:33:01 CEST 2009


Hi there,
I wonder if there is a parallel pipeline in blender. I mean the
pipeline as that in CPU which increase IPC (instructions per cycle).
I'm considering implement that feature.
Let me make it more clear.
Assuming the following interfaces is provided:

enum ThreadedPipelineStatus
{
        EMPTY,
        RUNNING,
        FULL
};

struct ThreadedPipelineOutcome
{
        enum ThreadedPipelineStatus stat;
        void *rtv;
};

struct ThreadedPipeline
{
        ListBase *      stage_list;             //list of pipeline stage (tasks)
        unsigned        buf_size;
        void *          in_buf[];
        unsigned        in_buf_head;
        unsigned        in_buf_tail;
        void *          out_buf[];
        unsigned        out_buf_head;
        unsigned        out_buf_tail;
};

struct ThreadedPipelineStage
{
        struct ThreadedPipelineStage *prev, *next;
        void * (*task)(void *);
};

/*
 * This function allocate a space for return, initialize its buffer
 * and setup @startup and @endup.
 * @startup should return the data's pointer to enter
 * the in_buf of pipeline, or NULL to drop the input.
 * @endup should return the data's pointer to enter
 * the out_buf of pipeline, or NULL to drop the input.
 */

struct ThreadedPipeline* BLI_init_threaded_pipeline
        (unsigned buf_size,
         void * (*startup)(void *),
         void * (*endup)(void *));

struct ThreadedPipeline* BLI_init_threaded_pipeline_add_task
        (struct ThreadedPipeline *pipeline, void * (*task)(void *));

struct ThreadedPipelineOutcome* BLI_run_threaded_pipeline
        (struct ThreadedPipeline* pipeline, void* data);

/*
 * This function free the space pointed by input, and all the resources
 * it takes. Also end all running tasks
 */
void BLI_destroy_threaded_pipeline(struct ThreadedPipeline *pipeline);

NOW, current code use these interfaces:

//the startup
void * foo_startup(void* input)
{
         some_data * data = input;
         if(data is OK)
         {
                  some_data * output = copyof(data);
                  return (void*)output;
         }
         return NULL;
}

//the endup
void * foo_endup(void* input)
{
         some_data * data = input;
         if(data is OK)
         {
                  return (void*)data;
         }
         return NULL;
}

struct ThreadedPipeline* pipeline = BLI_init_threaded_pipeline
struct ThreadedPipelineOutcome(2, foo_startup, foo_endup);
pipeline = BLI_init_threaded_pipeline_add_task( pipeline, task1);
pipeline = BLI_init_threaded_pipeline_add_task( pipeline, task2);
pipeline = BLI_init_threaded_pipeline_add_task( pipeline, task3);
pipeline = BLI_init_threaded_pipeline_add_task( pipeline, task4);
struct ThreadedPipelineOutcome outcome;
void* input;
int loop=1;
while(loop)
{
         if( i < len(data))
                 input = data[ i++ ];
         else
                 input = NULL;
         outcome = BLI_run_threaded_pipeline( pipeline, input );
         switch(outcome.stat){
         case FULL:
                  sleep for a while;
         case RUNNING:
                  do somthing with outcome.rtv;
                  break;
         case EMPTY:
                  loop=0;
                  break;
         }
}

BLI_destroy_threaded_pipeline(pipeline);

IN THIS WAY, the data in data[] can be processed by task[1-5] in
sequence one by one, but actually more than one element in data[] are
processed in parallel.
Any comments?

-- 
James Ruan


More information about the Bf-taskforce25 mailing list