コード例 #1
0
void parallel_wcc(graph_t &g, unsigned threadnum, vector<vector<uint64_t> > &global_input_tasks, gBenchPerf_multi &perf,
                  int perf_group)
{

    vector<vector<uint64_t> > global_output_tasks(threadnum*threadnum);

    bool stop = false;
    #pragma omp parallel num_threads(threadnum) shared(stop,global_input_tasks,global_output_tasks,perf)
    {
        unsigned tid = omp_get_thread_num();
        vector<uint64_t> & input_tasks = global_input_tasks[tid];

        perf.open(tid, perf_group);
        perf.start(tid, perf_group);
        while(!stop)
        {
            #pragma omp barrier
            // process local queue
            stop = true;


            for (unsigned i=0;i<input_tasks.size();i++)
            {
                uint64_t vid=input_tasks[i];
                uint64_t size, begin;
                size = g.csr_in_edges_size(vid);
                begin = g.csr_in_edges_begin(vid);
                for (uint64_t i=0;i<size;i++)
                {
                    uint64_t dest_vid = g.csr_in_edge(begin,i);
                    if(g.csr_vertex_property(dest_vid).root > g.csr_vertex_property(vid).root) {
                        __sync_bool_compare_and_swap(&(g.csr_vertex_property(dest_vid).root), g.csr_vertex_property(dest_vid).root, g.csr_vertex_property(vid).root);
                        global_output_tasks[vertex_distributor(dest_vid,threadnum)+tid*threadnum].push_back(dest_vid);
                    }
                }

                size = g.csr_out_edges_size(vid);
                begin = g.csr_out_edges_begin(vid);
                for (uint64_t i=0;i<size;i++)
                {
                    uint64_t dest_vid = g.csr_out_edge(begin,i);

                    bool done = false;
                    while(!done) {
                        if(g.csr_vertex_property(dest_vid).root > g.csr_vertex_property(vid).root) {
                            done = __sync_bool_compare_and_swap(&(g.csr_vertex_property(dest_vid).root), g.csr_vertex_property(dest_vid).root, g.csr_vertex_property(vid).root);
                            if(done) {
                                global_output_tasks[vertex_distributor(dest_vid,threadnum)+tid*threadnum].push_back(dest_vid);
                            }
                        } else {
                            done = true;
                        }
                    }
                }
            }
            #pragma omp barrier
            input_tasks.clear();
            for (unsigned i=0;i<threadnum;i++)
            {
                if (global_output_tasks[i*threadnum+tid].size()!=0)
                {
                    stop = false;
                    input_tasks.insert(input_tasks.end(),
                                       global_output_tasks[i*threadnum+tid].begin(),
                                       global_output_tasks[i*threadnum+tid].end());
                    global_output_tasks[i*threadnum+tid].clear();
                }
            }
#pragma omp barrier

        }
        perf.stop(tid, perf_group);
    }

}