Gemini代码摘抄(一)Graph和init

来源:互联网 发布:英语教师网络研修心得 编辑:程序博客网 时间:2024/06/16 09:58

Graph和init


在pagerank.cpp中对图进行初始化:

  Graph<Empty> * graph;  graph = new Graph<Empty>();

具体实现在graph.hpp中,设置threads和sockets,其中threads—cpus—partitionssockets—nodes—machines,threads_per_socket表示每个节点(机器)上分到的线程数(分区数):

 Graph() {    threads = numa_num_configured_cpus();    sockets = numa_num_configured_nodes();    threads_per_socket = threads / sockets;    init();  }

init()函数设置分区数

void init() {    edge_data_size = std::is_same<EdgeData, Empty>::value ? 0 : sizeof(EdgeData);    unit_size = sizeof(VertexId) + edge_data_size;    edge_unit_size = sizeof(VertexId) + unit_size;    assert( numa_available() != -1 );    assert( sizeof(unsigned long) == 8 ); // assume unsigned long is 64-bit    char nodestring[sockets*2+1];    nodestring[0] = '0';    for (int s_i=1;s_i<sockets;s_i++) {      nodestring[s_i*2-1] = ',';      nodestring[s_i*2] = '0'+s_i;    }    struct bitmask * nodemask = numa_parse_nodestring(nodestring);    numa_set_interleave_mask(nodemask);    omp_set_dynamic(0);    omp_set_num_threads(threads);    thread_state = new ThreadState * [threads];    local_send_buffer_limit = 16;    local_send_buffer = new MessageBuffer * [threads];    for (int t_i=0;t_i<threads;t_i++) {      thread_state[t_i] = (ThreadState*)numa_alloc_onnode( sizeof(ThreadState), get_socket_id(t_i));      local_send_buffer[t_i] = (MessageBuffer*)numa_alloc_onnode( sizeof(MessageBuffer), get_socket_id(t_i));      local_send_buffer[t_i]->init(get_socket_id(t_i));    }    #pragma omp parallel for    for (int t_i=0;t_i<threads;t_i++) {      int s_i = get_socket_id(t_i);      assert(numa_run_on_node(s_i)==0);      #ifdef PRINT_DEBUG_MESSAGES       printf("thread-%d bound to socket-%d\n", t_i, s_i);      #endif    }    #ifdef PRINT_DEBUG_MESSAGES     printf("threads=%d*%d\n", sockets, threads_per_socket);     printf("interleave on %s\n", nodestring);    #endif    MPI_Comm_rank(MPI_COMM_WORLD, &partition_id);    MPI_Comm_size(MPI_COMM_WORLD, &partitions);    send_buffer = new MessageBuffer ** [partitions];    recv_buffer = new MessageBuffer ** [partitions];    for (int i=0;i<partitions;i++) {      send_buffer[i] = new MessageBuffer * [sockets];      recv_buffer[i] = new MessageBuffer * [sockets];      for (int s_i=0;s_i<sockets;s_i++) {        send_buffer[i][s_i] = (MessageBuffer*)numa_alloc_onnode( sizeof(MessageBuffer), s_i);        send_buffer[i][s_i]->init(s_i);        recv_buffer[i][s_i] = (MessageBuffer*)numa_alloc_onnode( sizeof(MessageBuffer), s_i);        recv_buffer[i][s_i]->init(s_i);      }    }    alpha = 8 * (partitions - 1);    MPI_Barrier(MPI_COMM_WORLD);  }

2.收到的边数是收到的byte数除以每条边的大小:

int recv_edges = recv_bytes / edge_unit_size;

3.点dst所在的分区号为dst_part,
dst_part分区中点src的出边加一
点dst的入度加一
点src的初度加一

__sync_fetch_and_add(&outgoing_adj_index[dst_part][src], 1);__sync_fetch_and_add(&in_degree[dst], 1);__sync_fetch_and_add(&out_degree[src], 1);

4.alpha值为分区个数乘以8

原创粉丝点击