mic openmp 求dijkstra
2015-06-28 22:04
330 查看
</pre><pre name="code" class="cpp">#include <stdio.h> #include <iostream> #include <memory.h> #include <omp.h> using namespace std; #define NODENUM 264346 #define MAXNODENUM 1000000 #define MAXEDGENUM 4000000 #define THREADNUM 64 #define MAXINPUTLINE 512 #define s 0 // source // Graph info int f[MAXNODENUM]; // Distance to source int route[MAXNODENUM]; //route store the route int edge_l[MAXEDGENUM], edge_r[MAXEDGENUM], edge_dis[MAXEDGENUM]; // An edge's left and right endtime, and its distance int ad_next[MAXEDGENUM], ad_head[MAXNODENUM]; // Use adjacency list to store graph. For each point, use a list to store its adjacent edges table. //ad_head is the list's first element(edge id), ad_next is each element(edge id)'s next pointer. int edge_cnt = 0; // Number of edges // Computation share memory int msg_head[2][THREADNUM][THREADNUM], msg_next[2][MAXEDGENUM]; // Use a list to store msgs sent to T_1 from T_2. T_0 is a rolling array flag for even or odd iteraion. int haltflag = 0, swflag = 0; // switch flag sets which msg_head and msg_next array we are loading and saving now. 0/1 only. // Others FILE *fp; // Input file char line[MAXINPUTLINE]; // Input line int x,y,z; // Input tmp integer double starttime, endtime; // Timer int iterationcnt; // Times of iteration int main(int argc, char** argv) { if((fp=fopen(argv[1],"r")) == NULL) { printf("Cannot open %s\n", argv[1]); return -1; } memset(ad_head,0,sizeof(ad_head)); // Input while (fgets(line, MAXINPUTLINE, fp)) { if (line[0] == 'a') sscanf(line+2, "%d %d %d", &x, &y, &z); // Edge data edge_r[++edge_cnt] = y; edge_l[edge_cnt] = x; edge_dis[edge_cnt] = z; // Adjacent table data. Use a list to store a point's adjacent edges. ad_next[edge_cnt] = ad_head[x]; ad_head[x] = edge_cnt; } printf("Input finished\n"); memset(f,0xFF,sizeof(f)); memset(msg_head,0,sizeof(msg_head)); // INITIALIZE f[s] = 0; // Distance from source node is 0 int firstthread = s % THREADNUM; for(int m = ad_head[s]; m != 0; m = ad_next[m]) // Traverse all adjacent edges of the source node { int x = edge_r[m] % THREADNUM; // The edge's other end's thread // Use a list to store msgs sent to x from firstthread. msg_next[swflag][m] = msg_head[swflag][x][firstthread]; msg_head[swflag][x][firstthread] = m; } haltflag = 0; swflag = 1; iterationcnt = 0; // START DIJKSTRA starttime = omp_get_wtime(); #pragma omp parallel num_threads(THREADNUM) { int tid = omp_get_thread_num(); int tmp_edge,updatenum; while(haltflag == 0) // When haltflag == 0, go on. { #pragma omp barrier #pragma omp master { iterationcnt++; // Count iteration times for result show. haltflag = 1; // Set haltflag to 1. swflag = 1 - swflag; // Change iteration switch flag. } #pragma omp barrier updatenum = 0; for(int i = 0; i < THREADNUM; i++) // Each thread check other thread's update { tmp_edge = msg_head[swflag][tid][i]; // Updated edge from msg sent from i to me. while(tmp_edge != 0) { int tmp_r = edge_r[tmp_edge]; int tmp_l = edge_l[tmp_edge]; if((f[tmp_r] == -1) || (f[tmp_r] > edge_dis[tmp_edge] + f[tmp_l])) // Better? { f[tmp_r] = edge_dis[tmp_edge] + f[tmp_l]; // Send msg to affected threads! for(int m = ad_head[tmp_r]; m != 0; m = ad_next[m]) { if(f[edge_r[m]] == -1 || f[edge_r[m]] > f[tmp_r] + edge_dis[m]) // better? { int x = edge_r[m] % THREADNUM; msg_next[1-swflag][m] = msg_head[1-swflag][x][tid]; // Put into the msg list(next) msg_head[1-swflag][x][tid] = m; // Msg list(head) } } } haltflag = 0; // Don't halt tmp_edge = msg_next[swflag][tmp_edge]; // List iterate: element = element's next } } #pragma omp barrier for(int i = 0; i < THREADNUM; i++) { msg_head[swflag][tid][i] = 0; //Clear last msg } } } // Show result time endtime = omp_get_wtime(); printf("data processed, loop for %d times\n",iterationcnt); printf("Lost time: %.3lfs\n", endtime-starttime); fclose(fp); }
相关文章推荐
- 利用Openssl生成证书
- 关于CRT连接虚拟机Linux系统的攻略
- CentOS Linux服务器安全设置
- linux下修改双系统默认启动级别
- OpenGL - obj文件的导入
- ecshop商品批量上传之EC助理1.28支持ECshop2.7.3方法
- Linux流量监控工具 - iftop (最全面的iftop教程)
- 跟我一起hadoop(1)-hadoop2.6安装与使用
- opencv 数字图像处理-图像错切
- Linux 手动编译PHP 5.6
- cJSON(Linux C)
- linux文件空洞
- 基于OpenCV的摄像机标定-翻译
- linux程序设计——make命令和makefile文件(第九章)
- 安全测试外包 简单搞定网站安全问题
- shell十三问(转)
- dev-ops
- Play HEVC/H.265 Videos and Embed HEVC Streams into MP4 and TS Files with openHEVC and GPAC
- spark、storm与Hadoop
- FIO是测试IOPS的 支持13种不同的I/O引擎