# Persistent Caching ###### tags: `GPU` ###### members: @林孟賢 @席致寧 [paper](https://www.overleaf.com/3161447213kchpscspbmxk) [proposal](https://docs.google.com/document/d/1LPxwv7mzae4n1qHnJnDLL_UtjeJf0ngaChi5H_2DfHM/edit?usp=sharing) [report](https://drive.google.com/file/d/152gvtqASZaRv1jkt5Guig8FHHtJiFg0R/view?usp=sharing) [spreadsheet](https://docs.google.com/spreadsheets/d/197LhQm2fDLeWsN5sECN_cid8bA1nde6RrRPaRqrWZp8/edit#gid=0) [slide](https://docs.google.com/presentation/d/1Thz_tu13iYqtAW99xmj1XgWEpikkIbobYvLYku2fkGw/edit?usp=sharing) [oral test](https://docs.google.com/presentation/d/12lGzoFUw9xnw112_kMmgaDO5RW0ygAmvc0cVbPRxzM4/edit?usp=sharing) [reference ppaer](https://hackmd.io/867BaaD-QIe1ytWs7FXYpQ) [DAC paper bullet point](https://hackmd.io/ES09vnUQT-KgcvPX5h2fVw?both) ## Idea ![](https://i.imgur.com/vIoz63Q.png) ![](https://i.imgur.com/oMXxn4J.png) <!-- ![](https://i.imgur.com/CycLrc0.png)--> ![](https://i.imgur.com/kcoBzo5.png) ![](https://i.imgur.com/bxPxGry.png) * spare register([reference paper](https://ieeexplore.ieee.org/abstract/document/6835970)) * Due to resource constraints there may be unallocated registers in a GPU. * If a thread warp has terminated, then registers allocated to the warp are free. * register file access * ![](https://i.imgur.com/9QIySp9.png) * new version of gpgpu-sim contain **Operand collector** which contain a cross-bar, and can access all register file * ![](https://i.imgur.com/pdAiXtc.png) * compiler assist * programming interface like openMP * need user to specify the independent for loop * need compiler to calculate the usage of register numbers in each iteration. * **到達定植分析**可以找出**循環不便變量** * runtime * in runtime we need a table to record the index of the for loop in each thread ### Compare to Software Solution additional space required by software solution : * `length[]` * 紀錄一個warp裡面每條thread所需要的iteration * additional space : O(V) * `start[]` * 紀錄一個warp裡面每條thread的起始位置 * additional space : O(V) * `origin_thread[]` * 紀錄每條邊來自於那一條thread * additional space : O(E) additional space required by hardware solution : * `index_table` * 紀錄一個warp裡面每條thread的start 跟 end * additional space : O(V) 1. hardware solution是rum time生成table, 當某條warp完成運算後即可release掉空間,所以實際上花的空間不會那麼多 2. software solution 會有 preprocessing kernel overhead 3. software solution要先將data(start, length, ...)存在global memory,hardware solution則是extend hardware component來存run time生成的table 4. software solution的memory access次數會變多 ## Related paper list * hardware * Graph-Waving architecture: Efficient execution of graph applications on GPUs * map each node to a warp instead of thread * need to change the user’s code * need to eliminate duplicate scaler instruction * Dynamic Thread Block Launch: A Lightweight Execution Mechanism toSupport Irregular Applications on GPUs * use dynamic launch “thread block” to replace dynamic launch “kernel”, thus alleviate the overhead of the “kernel” and increase parallelism * not fully utilized the SIMD lane when degree of the node is small * GraphPEG: Accelerating Graph Processing on GPUs * use “hardware function” to collect needed edges to the “shared memory”, then process on the collected edge * solve all the aforemention problem, but add many additional hardwares * Accelerating Irregular Algorithms on GPGPUs Using Fine-Grain Hardware Worklists * Active Thread Compaction for GPU Path Tracing * software * gunrock * Accelerating CUDA Graph Algorithms at Maximum Warp * [paper](https://stanford-ppl.github.io/website/papers/ppopp070a-hong.pdf) * Work-Efficient Parallel GPU Methods for Single-Source Shortest Paths * [paper](https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=6877269) * Scalable GPU Graph Traversal * [paper](https://mgarland.org/files/papers/gpubfs.pdf) * benchmark * Pannotia: Understanding Irregular GPGPU Graph Applications * [paper](https://www.cs.virginia.edu/~skadron/Papers/Che-pannotia-iiswc2013.pdf) ## problem of equivalence software solution * atomic * ## solve active/inactive ![](https://i.imgur.com/bRnCHU5.gif) ## graph [pannotia](https://github.com/pannotia/pannotia/wiki) [datasets](https://www.cc.gatech.edu/dimacs10/archive/coauthor.shtml) ## PTX ### SPMV * original code: ``` cvta.to.global.u64 %rd2, %rd13; cvta.to.global.u64 %rd17, %rd12; cvta.to.global.u64 %rd18, %rd10; mul.wide.s32 %rd19, %r15, 4; #move add.s64 %rd26, %rd17, %rd19; #move add.s64 %rd25, %rd18, %rd19; #move BB0_3: .pragma "nounroll"; ld.global.u32 %r14, [%rd26]; # PC=0x100 mul.wide.s32 %rd20, %r14, 4; add.s64 %rd21, %rd2, %rd20; ld.global.f32 %f4, [%rd21]; ld.global.f32 %f5, [%rd25]; mul.f32 %f6, %f5, %f4; atom.shared.add.f32 %f7, [%r3], %f6; add.s64 %rd26, %rd26, 4; add.s64 %rd25, %rd25, 4; add.s32 %r15, %r15, 1; setp.lt.s32 %p3, %r15, %r5; @%p3 bra BB0_3; # PC=0x158 ``` * modified code ``` cvta.to.global.u64 %rd2, %rd13; cvta.to.global.u64 %rd17, %rd12; cvta.to.global.u64 %rd18, %rd10; # PC=0x0e0 add.s32 %r1, %r5, %r15; # PC=0x0e8 BB0_3: .pragma "nounroll"; mul.wide.s32 %rd19, %r15, 4; # PC=0x0f0 add.s64 %rd26, %rd17, %rd19; add.s64 %rd25, %rd18, %rd19; ld.global.u32 %r14, [%rd26]; mul.wide.s32 %rd20, %r14, 4; add.s64 %rd21, %rd2, %rd20; ld.global.f32 %f4, [%rd21]; ld.global.f32 %f5, [%rd25]; mul.f32 %f6, %f5, %f4; atom.shared.add.f32 %f7, [%r3], %f6; @%p3 bra BB0_3; # PC=0x140 ``` ### Pagerank * original code : ```c= #pragma unroll 1 for (int edge = start; edge < end; edge++) { int nid = col[edge]; atomicAdd(&page_rank2[nid], page_rank1[tid] / (float)(end - start)); } ``` ```= mul.wide.s32 %rd16, %r16, 4; add.s64 %rd19, %rd14, %rd16; //0x0e8 create table BB0_5: .pragma "nounroll"; ld.global.u32 %r14, [%rd19]; //0x0f0 col[edge] mul.wide.s32 %rd17, %r14, 4; add.s64 %rd18, %rd2, %rd17; ld.global.f32 %f2, [%rd3]; div.rn.f32 %f3, %f2, %f1; atom.global.add.f32 %f4, [%rd18], %f3; add.s64 %rd19, %rd19, 4; //0x120 edge++ add.s32 %r16, %r16, 1; //0x128 loop counter setp.lt.s32 %p4, %r16, %r15; //0x130 loop counter < iteration @%p4 bra BB0_5; //0x138 branch ``` * instruction找到0x0e8就換方式執行(還沒建表格) : ```= sub.s32 %r13, %r15, %r16; //PC = 0x0d0 cvt.rn.f32.s32%f1, %r13; //PC = 0x0d8 BB0_5: .pragma "nounroll"; mul.wide.s32 %rd16, %r16, 4; //PC = 0x0e0 r16 : index,從table拿 add.s64 %rd19, %rd14, %rd16; //PC = 0x0e8 rd14 : base address ld.global.u32 %r14, [%rd19]; mul.wide.s32 %rd17, %r14, 4; add.s64 %rd18, %rd2, %rd17; ld.global.f32 %f2, [%rd3]; div.rn.f32 %f3, %f2, %f1; atom.global.add.f32 %f4, [%rd18], %f3; //PC = 0x118 add.s32 %r16, %r16, 1; setp.lt.s32 %p4, %r16, %r15; @%p4 bra BB0_5; //PC = 0x130 ``` * %r16 : start, %r15 : end, 建表格 * 根據表格抓rd19的值 * gpu-sim要得到的資訊 : * start index * end index * last codeblock PC (第11行) * exit PC (第15行) ```= //PC = 0x0c8 sub.s32 %r13, %r15, %r16; //PC = 0x0d0 cvt.rn.f32.s32%f1, %r13; //PC = 0x0d8 create table add.s32 %r1, %r15, %r16; //PC = 0x0e0 set index BB0_5: .pragma "nounroll"; mul.wide.s32 %rd16, %r16, 4; //PC = 0x0e8 r16 : index, 從table拿 add.s64 %rd19, %rd14, %rd16; //PC = 0x0f0 rd14 : base address ld.global.u32 %r14, [%rd19]; //PC = 0x0f8 rd19 redirect??? mul.wide.s32 %rd17, %r14, 4; //PC = 0x100 add.s64 %rd18, %rd2, %rd17; //PC = 0x108 ld.global.f32 %f2, [%rd3]; //PC = 0x110 rd3 redirect??? div.rn.f32 %f3, %f2, %f1; //PC = 0x118 atom.global.add.f32 %f4, [%rd18], %f3; //PC = 0x120 @%p4 bra BB0_5; //PC = 0x128 //PC = 0x130 ``` read reg: write reg: rd16, rd19, r14, rd17, rd18, f2, f3, f4 ### Pagerank_spmv ``` cvta.to.global.u64 %rd2, %rd12; cvta.to.global.u64 %rd17, %rd10; cvta.to.global.u64 %rd18, %rd11; mul.wide.s32 %rd19, %r15, 4; #move add.s64 %rd26, %rd17, %rd19; #move add.s64 %rd25, %rd18, %rd19; #move add.s32 %r1, %r4, %r15; #add BB2_3: .pragma "nounroll"; ld.global.u32 %r14, [%rd26]; #PC=0x4e0 mul.wide.s32 %rd20, %r14, 4; #PC=0x4e8 add.s64 %rd21, %rd2, %rd20; #PC=0x4f0 ld.global.f32 %f4, [%rd21]; #PC=0x4f8 ld.global.f32 %f5, [%rd25]; #PC=0x500 mul.f32 %f6, %f5, %f4; #PC=0x508 atom.shared.add.f32 %f7, [%r5], %f6; #PC=0x510 add.s64 %rd26, %rd26, 4; #PC=0x518 delete add.s64 %rd25, %rd25, 4; #PC=0x520 delete add.s32 %r15, %r15, 1; #PC=0x528 delete setp.lt.s32 %p3, %r15, %r4; #PC=0x530 delete @%p3 bra BB2_3; #PC=0x538 ld.shared.f32 %f10, [%r5]; BB2_5: cvta.to.global.u64 %rd22, %rd13; shl.b64 %rd23, %rd1, 2; add.s64 %rd24, %rd22, %rd23; ld.global.f32 %f8, [%rd24]; add.f32 %f9, %f10, %f8; st.global.f32 [%rd24], %f9; BB2_6: ret; ``` #### parallel ``` cvta.to.global.u64 %rd2, %rd12; cvta.to.global.u64 %rd17, %rd10; cvta.to.global.u64 %rd18, %rd11; #PC=0x4c0 add.s32 %r1, %r4, %r15; #PC=0x4c8 add BB2_3: .pragma "nounroll"; mul.wide.s32 %rd19, %r15, 4; #PC=0x4d0 move add.s64 %rd26, %rd17, %rd19; #PC=0x4d8 move add.s64 %rd25, %rd18, %rd19; #PC=0x4e0 move ld.global.u32 %r14, [%rd26]; #PC=0x4e8 mul.wide.s32 %rd20, %r14, 4; #PC=0x4f0 add.s64 %rd21, %rd2, %rd20; #PC=0x4f8 ld.global.f32 %f4, [%rd21]; #PC=0x500 ld.global.f32 %f5, [%rd25]; #PC=0x508 mul.f32 %f6, %f5, %f4; #PC=0x510 atom.shared.add.f32 %f7, [%r5], %f6; #PC=0x518 @%p3 bra BB2_3; #PC=0x520 ld.shared.f32 %f10, [%r5]; BB2_5: cvta.to.global.u64 %rd22, %rd13; shl.b64 %rd23, %rd1, 2; add.s64 %rd24, %rd22, %rd23; ld.global.f32 %f8, [%rd24]; add.f32 %f9, %f10, %f8; st.global.f32 [%rd24], %f9; BB2_6: ret; ``` ### BC ``` //PC=0x0d0 BB0_4: setp.ge.s32 %p4, %r22, %r21; //PC=0x0d8 @%p4 bra BB0_11; //PC=0x0e0 cvta.to.global.u64 %rd18, %rd11; //PC=0x0e8 cvta.to.global.u64 %rd19, %rd9; //PC=0x0f0 add.s32 %r5, %r13, 1; //PC=0x0f8 add.s64 %rd2, %rd18, %rd14; //PC=0x100 cvta.to.global.u64 %rd4, %rd12; //PC=0x108 create table add.s32 %r1, %r21, %r22; //PC=0x110 extend set index BB0_6: .pragma "nounroll"; mul.wide.s32 %rd21, %r22, 4; //PC=0x118 move, set register add.s64 %rd27, %rd19, %rd21; //PC=0x120 move ld.global.u32 %r7, [%rd27]; //PC=0x128 mul.wide.s32 %rd23, %r7, 4; //PC=0x130 add.s64 %rd6, %rd13, %rd23; //PC=0x138 ld.global.u32 %r23, [%rd6]; //PC=0x140 setp.gt.s32 %p5, %r23, -1; //PC=0x148 @%p5 bra BB0_8; //PC=0x150 mov.u32 %r19, 1; //PC=0x158 st.global.u32 [%rd4], %r19; //PC=0x160 *cont = 1; add.s32 %r20, %r13, 1; //PC=0x168 st.global.u32 [%rd6], %r20; //PC=0x170 d[w] = dist + 1; mov.u32 %r23, %r5; //PC=0x178 BB0_8: setp.ne.s32 %p6, %r23, %r5; //PC=0x180 break point r23: d[w], r5: @%p6 bra BB0_10; //PC=0x188 add.s64 %rd26, %rd18, %rd23; //PC=0x190 ld.global.f32 %f1, [%rd2]; //PC=0x198 atom.global.add.f32 %f2, [%rd26], %f1; //PC=0x1a0 BB0_10: add.s32 %r22, %r22, 1; //delete add.s64 %rd27, %rd27, 4; //delete setp.lt.s32 %p7, %r22, %r21; //delete @%p7 bra BB0_6; //PC=0x1a8 finish or not / destroy table BB0_11: ret; //PC=0x1b0 ``` ### BC_WL #### original ``` cvta.to.global.u64 %rd19, %rd12; cvta.to.global.u64 %rd20, %rd10; add.s32 %r6, %r14, 1; add.s64 %rd2, %rd19, %rd18; #PC=0x100 mul.wide.s32 %rd22, %r23, 4; #PC=0x108 move add.s64 %rd28, %rd20, %rd22; #PC=0x110 move cvta.to.global.u64 %rd4, %rd13; #PC=0x118 cvta.to.global.u64 %rd23, %rd11; #PC=0x120 add.s32 %r1, %r22, %r23; #PC=0x128 add BB0_5: .pragma "nounroll"; ld.global.u32 %r8, [%rd28]; #PC=0x130 mul.wide.s32 %rd24, %r8, 4; add.s64 %rd6, %rd23, %rd24; ld.global.u32 %r24, [%rd6]; setp.gt.s32 %p4, %r24, -1; @%p4 bra BB0_7; mov.u32 %r20, 1; st.global.u32 [%rd4], %r20; add.s32 %r21, %r14, 1; st.global.u32 [%rd6], %r21; mov.u32 %r24, %r6; BB0_7: setp.ne.s32 %p5, %r24, %r6; @%p5 bra BB0_9; add.s64 %rd27, %rd19, %rd24; ld.global.f32 %f1, [%rd2]; atom.global.add.f32 %f2, [%rd27], %f1; BB0_9: add.s32 %r23, %r23, 1; #remove add.s64 %rd28, %rd28, 4; #remove setp.lt.s32 %p6, %r23, %r22; #remove @%p6 bra BB0_5; ``` #### modified ``` cvta.to.global.u64 %rd19, %rd12; cvta.to.global.u64 %rd20, %rd10; add.s32 %r6, %r14, 1; #PC=0x100 add.s64 %rd2, %rd19, %rd18; #PC=0x108 cvta.to.global.u64 %rd4, %rd13; #PC=0x110 cvta.to.global.u64 %rd23, %rd11; #PC=0x118 add.s32 %r1, %r22, %r23; #PC=0x120 BB0_5: .pragma "nounroll"; mul.wide.s32 %rd22, %r23, 4; #PC=0x128 add.s64 %rd28, %rd20, %rd22; ld.global.u32 %r8, [%rd28]; mul.wide.s32 %rd24, %r8, 4; add.s64 %rd6, %rd23, %rd24; ld.global.u32 %r24, [%rd6]; setp.gt.s32 %p4, %r24, -1; @%p4 bra BB0_7; mov.u32 %r20, 1; st.global.u32 [%rd4], %r20; add.s32 %r21, %r14, 1; st.global.u32 [%rd6], %r21; mov.u32 %r24, %r6; BB0_7: setp.ne.s32 %p5, %r24, %r6; @%p5 bra BB0_9; add.s64 %rd27, %rd19, %rd24; ld.global.f32 %f1, [%rd2]; atom.global.add.f32 %f2, [%rd27], %f1; BB0_9: @%p6 bra BB0_5; #PC=0x1b8 ``` ### Color #### original original ``` BB0_4: mov.u32 %r33, -1; setp.ge.s32 %p4, %r2, %r30; @%p4 bra BB0_9; add.s32 %r5, %r30, -1; mov.u32 %r33, -1; cvta.to.global.u64 %rd17, %rd7; mul.wide.s32 %rd18, %r2, 4; //remove add.s64 %rd28, %rd17, %rd18; //remove cvta.to.global.u64 %rd3, %rd10; cvta.to.global.u64 %rd22, %rd8; mov.u32 %r31, %r2; //create table add.s32 %r1, %r31, %r30; //add, set index to table BB0_6: .pragma "nounroll"; mul.wide.s32 %rd18, %r31, 4; //move add.s64 %rd28, %rd17, %rd18; //move ld.global.u32 %r25, [%rd28]; //PC=0x130 mul.wide.s32 %rd20, %r25, 4; add.s64 %rd21, %rd12, %rd20; ld.global.u32 %r26, [%rd21]; setp.eq.s32 %p5, %r26, -1; setp.ne.s32 %p6, %r2, %r5; and.pred %p7, %p5, %p6; @!%p7 bra BB0_8; bra.uni BB0_7; BB0_7: mov.u32 %r27, 1; st.global.u32 [%rd3], %r27; ld.global.u32 %r28, [%rd28]; mul.wide.s32 %rd23, %r28, 4; add.s64 %rd24, %rd22, %rd23; ld.global.u32 %r29, [%rd24]; max.s32 %r33, %r29, %r33; BB0_8: add.s64 %rd28, %rd28, 4; //remove add.s32 %r31, %r31, 1; //remove setp.lt.s32 %p8, %r31, %r30; //remove r31 : index, r30 : end @%p8 bra BB0_6; BB0_9: cvta.to.global.u64 %rd25, %rd11; add.s64 %rd27, %rd25, %rd13; st.global.u32 [%rd27], %r33; BB0_10: ret; ``` modified ``` BB0_4: mov.u32 %r33, -1; setp.ge.s32 %p4, %r2, %r30; @%p4 bra BB0_9; add.s32 %r5, %r30, -1; mov.u32 %r33, -1; cvta.to.global.u64 %rd17, %rd7; cvta.to.global.u64 %rd3, %rd10; cvta.to.global.u64 %rd22, %rd8; mov.u32 %r31, %r2; //PC=0x118 create table add.s32 %r1, %r31, %r30; //PC=0x120 add, set index to table BB0_6: .pragma "nounroll"; mul.wide.s32 %rd18, %r31, 4; //PC=0x128 move add.s64 %rd28, %rd17, %rd18; //PC=0x130 move ld.global.u32 %r25, [%rd28]; //PC=0x138 mul.wide.s32 %rd20, %r25, 4; //PC=0x140 add.s64 %rd21, %rd12, %rd20; //PC=0x148 ld.global.u32 %r26, [%rd21]; //PC=0x150 setp.eq.s32 %p5, %r26, -1; //PC=0x158 setp.ne.s32 %p6, %r2, %r5; //PC=0x160 and.pred %p7, %p5, %p6; //PC=0x168 @!%p7 bra BB0_8; //PC=0x170 bra.uni BB0_7; //PC=0x178 BB0_7: mov.u32 %r27, 1; //PC=0x180 st.global.u32 [%rd3], %r27; //PC=0x188 ld.global.u32 %r28, [%rd28]; //PC=0x190 mul.wide.s32 %rd23, %r28, 4; //PC=0x198 add.s64 %rd24, %rd22, %rd23; //PC=0x1a0 ld.global.u32 %r29, [%rd24]; //PC=0x1a8 max.s32 %r33, %r29, %r33; //PC=0x1b0 BB0_8: @%p8 bra BB0_6; //PC=0x1b8 BB0_9: cvta.to.global.u64 %rd25, %rd11; add.s64 %rd27, %rd25, %rd13; st.global.u32 [%rd27], %r33; BB0_10: ret; ``` #### parallel original ``` add.s32 %r6, %r32, -1; cvta.to.global.u64 %rd18, %rd8; mul.wide.s32 %rd19, %r2, 4; //moved add.s64 %rd29, %rd18, %rd19; //moved cvta.to.global.u64 %rd4, %rd11; cvta.to.global.u64 %rd23, %rd9; mov.u32 %r33, %r2; // add.s32 %r1, %r32, %r33; //PC=, add BB0_6: .pragma "nounroll"; mul.wide.s32 %rd19, %r33, 4; //PC=, move add.s64 %rd29, %rd18, %rd19; //PC=, move ld.global.u32 %r22, [%rd29]; //PC=0x158 mul.wide.s32 %rd21, %r22, 4; //60 add.s64 %rd22, %rd13, %rd21; //68 ld.global.u32 %r23, [%rd22]; //70 setp.eq.s32 %p5, %r23, -1; //78 setp.ne.s32 %p6, %r2, %r6; //80 and.pred %p7, %p5, %p6; //88 @!%p7 bra BB0_8; //90 bra.uni BB0_7; //98 BB0_7: mov.u32 %r24, 1; //a0 st.global.u32 [%rd4], %r24; //a8 ld.global.u32 %r25, [%rd29]; //b0 mul.wide.s32 %rd24, %r25, 4; //b8 add.s64 %rd25, %rd23, %rd24; //c0 ld.global.u32 %r26, [%rd25]; //PC=0x1c8 atom.shared.max.s32 %r31, [%r5], %r26;//PC=0x1d0 BB0_8: add.s32 %r33, %r33, 1; //PC=0x1d8, remove add.s64 %rd29, %rd29, 4; //PC=0x1e0, remove setp.lt.s32 %p8, %r33, %r32; //PC=0x1e8, remove @%p8 bra BB0_6; //PC=0x1f0 ld.shared.u32 %r34, [%r5]; //PC=0x1f8 BB0_10: cvta.to.global.u64 %rd26, %rd12; add.s64 %rd28, %rd26, %rd17; st.global.u32 [%rd28], %r34; BB0_11: ret; ``` modified ``` add.s32 %r6, %r32, -1; cvta.to.global.u64 %rd18, %rd8; cvta.to.global.u64 %rd4, %rd11; cvta.to.global.u64 %rd23, %rd9; mov.u32 %r33, %r2; //PC=0x140 add.s32 %r1, %r32, %r33; //PC=0x148, add BB0_6: .pragma "nounroll"; mul.wide.s32 %rd19, %r33, 4; //PC=0x150, move add.s64 %rd29, %rd18, %rd19; //PC=0x158, move ld.global.u32 %r22, [%rd29]; //PC=0x160 mul.wide.s32 %rd21, %r22, 4; //PC=0x168 add.s64 %rd22, %rd13, %rd21; //PC=0x170 ld.global.u32 %r23, [%rd22]; //PC=0x178 setp.eq.s32 %p5, %r23, -1; //PC=0x180 setp.ne.s32 %p6, %r2, %r6; //PC=0x188 and.pred %p7, %p5, %p6; //PC=0x190 @!%p7 bra BB0_8; //PC=0x198 bra.uni BB0_7; //PC=0x1a0 BB0_7: mov.u32 %r24, 1; //PC=0x1a8 st.global.u32 [%rd4], %r24; //PC=0x1b0 ld.global.u32 %r25, [%rd29]; //PC=0x1b8 mul.wide.s32 %rd24, %r25, 4; //PC=0x1c0 add.s64 %rd25, %rd23, %rd24; //PC=0x1c8 ld.global.u32 %r26, [%rd25]; //PC=0x1d0 atom.shared.max.s32 %r31, [%r5], %r26;//PC=0x1d8 BB0_8: @%p8 bra BB0_6; //PC=0x1e0 ld.shared.u32 %r34, [%r5]; //PC=0x1e8 BB0_10: cvta.to.global.u64 %rd26, %rd12; add.s64 %rd28, %rd26, %rd17; st.global.u32 [%rd28], %r34; BB0_11: ret; ``` ### Color_wl original ``` add.s32 %r7, %r33, -1; cvta.to.global.u64 %rd18, %rd8; mul.wide.s32 %rd19, %r3, 4; #move add.s64 %rd29, %rd18, %rd19; #move cvta.to.global.u64 %rd3, %rd11; cvta.to.global.u64 %rd20, %rd10; cvta.to.global.u64 %rd23, %rd9; mov.u32 %r34, %r3; add.s32 %r1, %r33, %r34; #add BB0_5: .pragma "nounroll"; ld.global.u32 %r23, [%rd29]; #PC=0x348 mul.wide.s32 %rd21, %r23, 4; add.s64 %rd22, %rd20, %rd21; ld.global.u32 %r24, [%rd22]; setp.eq.s32 %p4, %r24, -1; setp.ne.s32 %p5, %r3, %r7; and.pred %p6, %p4, %p5; @!%p6 bra BB1_7; bra.uni BB1_6; BB1_6: mov.u32 %r25, 1; st.global.u32 [%rd3], %r25; ld.global.u32 %r26, [%rd29]; mul.wide.s32 %rd24, %r26, 4; add.s64 %rd25, %rd23, %rd24; ld.global.u32 %r27, [%rd25]; atom.shared.max.s32 %r32, [%r6], %r27; BB1_7: add.s32 %r34, %r34, 1; #remove add.s64 %rd29, %rd29, 4; #remove setp.lt.s32 %p7, %r34, %r33; #remove @%p7 bra BB1_5; ``` modified ``` add.s32 %r7, %r33, -1; cvta.to.global.u64 %rd18, %rd8; cvta.to.global.u64 %rd3, %rd11; cvta.to.global.u64 %rd20, %rd10; cvta.to.global.u64 %rd23, %rd9; mov.u32 %r34, %r3; #PC=0x140 add.s32 %r1, %r33, %r34; #PC=0x148 BB0_5: .pragma "nounroll"; mul.wide.s32 %rd19, %r34, 4; #PC=0x150 add.s64 %rd29, %rd18, %rd19; ld.global.u32 %r23, [%rd29]; mul.wide.s32 %rd21, %r23, 4; add.s64 %rd22, %rd20, %rd21; ld.global.u32 %r24, [%rd22]; setp.eq.s32 %p4, %r24, -1; setp.ne.s32 %p5, %r3, %r7; and.pred %p6, %p4, %p5; @!%p6 bra BB0_7; bra.uni BB0_6; BB0_6: mov.u32 %r25, 1; st.global.u32 [%rd3], %r25; ld.global.u32 %r26, [%rd29]; mul.wide.s32 %rd24, %r26, 4; add.s64 %rd25, %rd23, %rd24; ld.global.u32 %r27, [%rd25]; atom.shared.max.s32 %r32, [%r6], %r27; BB0_7: @%p7 bra BB0_5; #PC=0x1e0 ``` ### color max min ### origin ``` add.s32 %r5, %r52, -1; cvta.to.global.u64 %rd21, %rd6; mul.wide.s32 %rd22, %r2, 4; #move add.s64 %rd37, %rd21, %rd22; #move cvta.to.global.u64 %rd26, %rd9; cvta.to.global.u64 %rd27, %rd7; mov.u32 %r53, %r2; #PC=0x178 add.s32 %r1, %r52, %r53; #add BB0_6: .pragma "nounroll"; ld.global.u32 %r27, [%rd37]; #PC=0x180 mul.wide.s32 %rd24, %r27, 4; add.s64 %rd25, %rd12, %rd24; ld.global.u32 %r28, [%rd25]; setp.eq.s32 %p5, %r28, -1; setp.ne.s32 %p6, %r2, %r5; and.pred %p7, %p5, %p6; @!%p7 bra BB0_8; bra.uni BB0_7; BB0_7: mov.u32 %r29, 1; st.global.u32 [%rd26], %r29; ld.global.u32 %r30, [%rd37]; mul.wide.s32 %rd28, %r30, 4; add.s64 %rd29, %rd27, %rd28; ld.global.u32 %r31, [%rd29]; atom.shared.max.s32 %r36, [%r24], %r31; ld.global.u32 %r37, [%rd37]; mul.wide.s32 %rd30, %r37, 4; add.s64 %rd31, %rd27, %rd30; ld.global.u32 %r38, [%rd31]; atom.shared.min.s32 %r41, [%r26], %r38; BB0_8: add.s32 %r53, %r53, 1; #delete add.s64 %rd37, %rd37, 4; #delete setp.lt.s32 %p8, %r53, %r52; #delete @%p8 bra BB0_6; #PC=0x240 ld.shared.u32 %r55, [%r24]; ld.shared.u32 %r54, [%r26]; ``` ### parallel ``` add.s32 %r5, %r52, -1; cvta.to.global.u64 %rd21, %rd6; cvta.to.global.u64 %rd26, %rd9; cvta.to.global.u64 %rd27, %rd7; mov.u32 %r53, %r2; #PC=0x168 add.s32 %r1, %r52, %r53; #PC=0x170 add BB0_6: .pragma "nounroll"; mul.wide.s32 %rd22, %r53, 4; #PC=0x178 move add.s64 %rd37, %rd21, %rd22; #PC=0x180 move ld.global.u32 %r27, [%rd37]; #PC=0x mul.wide.s32 %rd24, %r27, 4; add.s64 %rd25, %rd12, %rd24; ld.global.u32 %r28, [%rd25]; setp.eq.s32 %p5, %r28, -1; setp.ne.s32 %p6, %r2, %r5; and.pred %p7, %p5, %p6; @!%p7 bra BB0_8; bra.uni BB0_7; BB0_7: mov.u32 %r29, 1; st.global.u32 [%rd26], %r29; ld.global.u32 %r30, [%rd37]; mul.wide.s32 %rd28, %r30, 4; add.s64 %rd29, %rd27, %rd28; ld.global.u32 %r31, [%rd29]; atom.shared.max.s32 %r36, [%r24], %r31; ld.global.u32 %r37, [%rd37]; mul.wide.s32 %rd30, %r37, 4; add.s64 %rd31, %rd27, %rd30; ld.global.u32 %r38, [%rd31]; atom.shared.min.s32 %r41, [%r26], %r38; BB0_8: @%p8 bra BB0_6; #PC=0x230 ld.shared.u32 %r55, [%r24]; ld.shared.u32 %r54, [%r26]; ``` ### mis #### origin ``` cvta.to.global.u64 %rd4, %rd10; cvta.to.global.u64 %rd19, %rd9; mul.wide.s32 %rd20, %r29, 4; #move add.s64 %rd28, %rd19, %rd20; #move BB1_6: .pragma "nounroll"; ld.global.u32 %r9, [%rd28]; #PC=0x210 mul.wide.s32 %rd21, %r9, 4; add.s64 %rd22, %rd1, %rd21; ld.global.u32 %r25, [%rd22]; setp.ne.s32 %p5, %r25, -1; @%p5 bra BB1_8; add.s64 %rd24, %rd4, %rd21; ld.global.u32 %r26, [%rd24]; atom.shared.min.s32 %r27, [%r6], %r26; BB1_8: add.s32 %r29, %r29, 1; #delete add.s64 %rd28, %rd28, 4; #delete setp.lt.s32 %p6, %r29, %r28; #delete @%p6 bra BB1_6; ld.shared.u32 %r30, [%r6]; BB1_10: cvta.to.global.u64 %rd25, %rd11; add.s64 %rd27, %rd25, %rd18; st.global.u32 [%rd27], %r30; BB1_11: ret; ``` #### modified ``` cvta.to.global.u64 %rd4, %rd10; cvta.to.global.u64 %rd19, %rd9; #PC=0x1f8 add.s32 %r1, %r28, %r29; #PC=0x200 add BB1_6: .pragma "nounroll"; mul.wide.s32 %rd20, %r29, 4; #PC=0x208 move add.s64 %rd28, %rd19, %rd20; #PC=0x210 move ld.global.u32 %r9, [%rd28]; #PC=0x218 mul.wide.s32 %rd21, %r9, 4; #PC=0x220 add.s64 %rd22, %rd1, %rd21; #PC=0x228 ld.global.u32 %r25, [%rd22]; #PC=0x230 setp.ne.s32 %p5, %r25, -1; #PC=0x238 @%p5 bra BB1_8; #PC=0x240 add.s64 %rd24, %rd4, %rd21; #PC=0x248 ld.global.u32 %r26, [%rd24]; #PC=0x250 atom.shared.min.s32 %r27, [%r6], %r26; #PC=0x258 BB1_8: @%p6 bra BB1_6; #PC=0x260 ld.shared.u32 %r30, [%r6]; #PC=0x268 BB1_10: cvta.to.global.u64 %rd25, %rd11; add.s64 %rd27, %rd25, %rd18; st.global.u32 [%rd27], %r30; BB1_11: ret; ``` ### mis_wl #### origin ``` cvta.to.global.u64 %rd2, %rd10; cvta.to.global.u64 %rd3, %rd11; cvta.to.global.u64 %rd20, %rd9; #PC=0x1f8 mul.wide.s32 %rd21, %r30, 4; #PC=0x200 move add.s64 %rd29, %rd20, %rd21; #PC=0x208 move add.s32 %r1, %r29, %r30; #add BB1_5: .pragma "nounroll"; ld.global.u32 %r10, [%rd29]; #PC=0x210 mul.wide.s32 %rd22, %r10, 4; add.s64 %rd23, %rd3, %rd22; ld.global.u32 %r26, [%rd23]; setp.ne.s32 %p4, %r26, -1; @%p4 bra BB1_7; add.s64 %rd25, %rd2, %rd22; ld.global.u32 %r27, [%rd25]; atom.shared.min.s32 %r28, [%r7], %r27; BB1_7: add.s32 %r30, %r30, 1; #remove add.s64 %rd29, %rd29, 4; #remove setp.lt.s32 %p5, %r30, %r29; #remove @%p5 bra BB1_5; ``` #### modified ``` cvta.to.global.u64 %rd2, %rd10; #PC=0x1e8 cvta.to.global.u64 %rd3, %rd11; #PC=0x1f0 cvta.to.global.u64 %rd20, %rd9; #PC=0x1f8 add.s32 %r1, %r29, %r30; #PC=0x200 BB1_5: .pragma "nounroll"; mul.wide.s32 %rd21, %r30, 4; #PC=0x208 add.s64 %rd29, %rd20, %rd21; ld.global.u32 %r10, [%rd29]; mul.wide.s32 %rd22, %r10, 4; add.s64 %rd23, %rd3, %rd22; ld.global.u32 %r26, [%rd23]; setp.ne.s32 %p4, %r26, -1; @%p4 bra BB1_7; add.s64 %rd25, %rd2, %rd22; ld.global.u32 %r27, [%rd25]; atom.shared.min.s32 %r28, [%r7], %r27; BB1_7: @%p5 bra BB1_5; #PC=0x260 ``` ### sssp #### origin ``` cvta.to.global.u64 %rd19, %rd11; cvta.to.global.u64 %rd20, %rd10; mul.wide.s32 %rd21, %r24, 4; #move add.s64 %rd28, %rd20, %rd21; #move add.s64 %rd27, %rd19, %rd21; #move BB0_3: .pragma "nounroll"; ld.global.u32 %r19, [%rd28]; #PC=0x100 mul.wide.s32 %rd22, %r19, 4; add.s64 %rd23, %rd17, %rd22; ld.global.u32 %r20, [%rd23]; ld.global.u32 %r21, [%rd27]; add.s32 %r22, %r20, %r21; atom.shared.min.s32 %r23, [%r6], %r22; add.s64 %rd28, %rd28, 4; #delete add.s64 %rd27, %rd27, 4; #delete add.s32 %r24, %r24, 1; #delete setp.lt.s32 %p3, %r24, %r4; #delete @%p3 bra BB0_3; ld.shared.u32 %r25, [%r6]; BB0_5: cvta.to.global.u64 %rd24, %rd13; shl.b64 %rd25, %rd1, 2; add.s64 %rd26, %rd24, %rd25; st.global.u32 [%rd26], %r25; BB0_6: ret; ``` #### modified ``` cvta.to.global.u64 %rd19, %rd11; cvta.to.global.u64 %rd20, %rd10; #PC=0x0e0 add.s32 %r1, %r4, %r24; #PC=0x0e8 add BB0_3: .pragma "nounroll"; mul.wide.s32 %rd21, %r24, 4; #PC=0x0f0 move add.s64 %rd28, %rd20, %rd21; #PC=0x0f8 move add.s64 %rd27, %rd19, %rd21; #PC=0x100 move ld.global.u32 %r19, [%rd28]; #PC=0x108 mul.wide.s32 %rd22, %r19, 4; #PC=0x110 add.s64 %rd23, %rd17, %rd22; #PC=0x118 ld.global.u32 %r20, [%rd23]; ld.global.u32 %r21, [%rd27]; add.s32 %r22, %r20, %r21; atom.shared.min.s32 %r23, [%r6], %r22; @%p3 bra BB0_3; #PC=0x140 ld.shared.u32 %r25, [%r6]; BB0_5: cvta.to.global.u64 %rd24, %rd13; shl.b64 %rd25, %rd1, 2; add.s64 %rd26, %rd24, %rd25; st.global.u32 [%rd26], %r25; BB0_6: ret; ``` --- ## outcome [spreadsheet](https://docs.google.com/spreadsheets/d/197LhQm2fDLeWsN5sECN_cid8bA1nde6RrRPaRqrWZp8/edit#gid=0) ### normal * pagerank * speedup : 2.02x * iterations : 26.6% * memory access number: 62.9% * BFS * speedup : 1.08x * iterations : 84.9% * memory access number: 41.4% * Color Max(pagerank graph) * speedup : 2.32x * iterations : 26.6% * memory access number: 15.2% * MIS(pagerank graph) * speedup : 1.91x * iterations : 26.6% * memory access number: 21.6% * SSSP * speedup : 1.97x * iterations : 26.6% * memory access number: 13.1% ### bypass l1 cache * Color Max * speedup : 1.49x * iterations : 99.9% * memory access number: 66.2% ### working list * BFS * gpgpu-sim's bug in global atomic increment * might because atom's outcome will not shown immediately * wl code has bug * speedup : x * iterations : % * memory access number: % --- ## Run Benchmarks [experiment spread sheet](https://docs.google.com/spreadsheets/d/12SWUiwHGojaicbE4O3QcscHBK07e-__A8j6FICQJRYQ/edit#gid=1338197220) [教授spread sheet](https://docs.google.com/spreadsheets/d/14ibl-NsZcrZzOVNC3gcKF7Ow2tnZt8DKzSlhPU888ak/edit#gid=283140300) ![](https://i.imgur.com/sPtCltQ.png) ### Loop Unroll ```cpp= #pragma unroll 1 for(int i=start; i<end; i++){ ... } ``` * `#pragma unroll N`會告訴compiler要unroll幾層loop * N=1只會unroll一層,即**turn off** loop unroll ### atomic operation * instruciton.cc * atom_impl * thread->m_last_dram_callback.function_wt * cuda-sim.cc * ptx_exec_inst * inst.add_callback(lane_id, last_callback().function_wt, last_callback().instruction, this, threads, true /*atomic*/); * abstract_hardware_model.cc * do_atomic * cb.function_wt(cb.instruction, cb.thread, cb.threads); * abstract_hardware_model.h * add_callback * dram_callback_t ### 1. gpgpusim.config ``` #lemonsien -gpgpu_perfect_mem 0 -gpgpu_concurrent_kernel_sm 1 -scheduler_kind 2 -partition_method 1 ... ... # high level architecture configuration -gpgpu_n_clusters 30 ... ... # Device Limits -gpgpu_kernel_launch_latency 0 ``` -cache allocate policy : 改成on miss, hit reserved才會正確 * 否則都是當成miss -scheduler_kind * 0:origin * 1:paver * 2:paver2 -partition_method * 0:BCS * 1:k-way * 2:recursive(not working) ### 2. Run ``` #pannotia/fw ./fw ../../../../data_dirs/pannotia/fw/data/256_16384.gr &> output_memstall & ``` ``` #pannotia/bc ./bc ../../../../data_dirs/pannotia/bc/data/1k_128k.gr &> output_paver_30groups_MST_ideal & ``` ``` #pannotia/color_max ./color_max ../../../../data_dirs/pannotia/color_max/data/ecology1.graph 1 &> output_paver_30groups_MST_ideal & ``` ``` #pannotai/sssp ./sssp ../../../../data_dirs/pannotia/sssp/data/USA-road-d.NW.gr 1 &> output_paver_30groups_MST_ideal & ``` ``` #pannotia/pagerank ./pagerank ../../../../data_dirs/pannotia/pagerank/data/coAuthorsDBLP.graph 1 &> output_paver2 & ``` ``` #pannotia/sssp ./sssp ../../../../data_dirs/pannotia/sssp/data/USA-road-d.NW.gr 0 &> output_memstall2 & ``` ``` #lonestar/mst ./run &> output_paver_30groups_MST_ideal & ``` ``` #lonestar/sssp ./sssp ../../../../../data_dirs/cuda/lonestargpu-2.0/inputs/USA-road-d.FLA.gr &> output_memstall2 & ``` ``` #mis ./mis data/ecology1.graph 1 &> output_memstall & ``` ## Git http://blog.gogojimmy.net/2012/02/29/git-scenario/ ``` git commit -am "comments" git push -u origin branch_name git pull origin branch_name ``` #### Log in ``` git config --global user.name "<使用者名字>" git config --global user.email "<電子信箱>" ``` check configure: ``` git config --list or cat ~/.gitconfig ``` #### 看狀態 ``` git status ``` #### 看歷史commit ``` git log ``` #### 加入新(untracked)檔案 ``` git add file_name ``` 一次加全部檔案: ``` git add . ``` #### 存檔, 會紀錄改過的檔案的訊息 ``` git commit -m "commit訊息" ``` 先git add .後略過編輯器提交 commit ``` git commit -am "commit訊息" ``` #### Branch 新增branch ``` git branch new_branch ``` 查看有哪些branch ``` git branch ``` 切換branch ``` git checkout target_branch ``` #### merge branch_name到目前的branch ``` git merge branch_name ``` ## Perfect Memory * access memory * 不access memory,"**去memory**" 馬上接 "**回cluster**" ![](https://i.imgur.com/5LjCpZQ.png) ![](https://i.imgur.com/ObHo7W6.png) ### memory stall * kinds * memory_cycle * memory access not done * shared_cycle * constant_cycle * texture_cycle * memory priority * ICNT_RC_FAIL = BK_CONF > COAL_STALL NO_RC_FAIL = 0, BK_CONF, MSHR_RC_FAIL, ICNT_RC_FAIL, COAL_STALL, TLB_STALL, DATA_PORT_STALL, WB_ICNT_RC_FAIL, WB_CACHE_RSRV_FAIL, N_MEM_STAGE_STALL_TYPE ## 相關論文 ### irregular benchmark * Graph-Waving architecture: Efficient execution of graph applications on GPUs * [link](https://www.sciencedirect.com/science/article/pii/S0743731520303889) * node to warp mapping, eliminate duplicate execution, shrink the warp size. * Fine-Grained Management of Thread Blocks for Irregular Applications * [link](https://ieeexplore.ieee.org/abstract/document/8988776?casa_token=mPwWuVZ8uekAAAAA:g3-72tUqQEa0RrzLppSWgs1erUiF5kwMhDruh5wyMgWfSJos8Q9pVCEiALDTIbiXQi0t7yPwGj4) 2019 * irregular application(graph)的狀態會隨著時間而改變(因為少數node關聯度很高) * 用前1個kernel的TB去預測下一個kernel的TB的狀態 * 及時追蹤每一個TB的現在的狀態 * 狀態包括Load-Store unit stall,Floating-Point Unit的使用度 * 根據這些狀態去調整SM中TB的數目,允許preemption * gain 17% and 13% improvements of throughput over previously proposed static and dynamic scheduling strategies, respectively * Dynamic Thread Block Launch: A Lightweight Execution Mechanism toSupport Irregular Applications on GPUs * [link](https://dl.acm.org/doi/epdf/10.1145/2872887.2750393) 2015 * 為了加速irregular application,這篇論文讓thread可以產生child thread block * 譬如:有些graph的每個thread會用for loop去traverse某個node的neighbor,每個node的neighbor不同時,會很分散。若是create一個child kernel或child thread block去concurrent執行所有的neighbor會很有用 * 1.21x speedup over the original flat implementation and average 1.40x over the implementations using device-kernel launch functionality * A quantitative study of irregular programs on GPUs * [link](https://ieeexplore.ieee.org/abstract/document/6402918) * Pannotia: Understanding irregular GPGPU graph applications * [link](https://ieeexplore.ieee.org/abstract/document/6704684) * Adaptive Page Migration for Irregular Data-intensive Applications under GPU Memory Oversubscription * [link](https://ieeexplore.ieee.org/document/9139797) * working sets of irregular applications can often be divided into cold and hot data structures. * cold allocations are accessed seldom and sparsely * hot data structures have dense sequential access * propose a dynamic page placement strategy for irregular general purpose applications differentiate between hot and cold allocations * performance improvement of 22% to 78% * Optimizing non-coalesced memory access for irregular applications with GPU computing * [link](https://link.springer.com/content/pdf/10.1631/FITEE.1900262.pdf) 2020 * software solution with no hardware extensions to solve dynamic irregularities * data reordering * eliminate indirect memory access by copying to a new location and reordering * Index redirection * reduce overhead * for loop拿到kernel外面,run multiple streams of kernels(1 for count, others for remap) * For loop-carried applications, reordered data are cached for the next iteration or other kernels to eliminate possible redundant data reorganization * 7.0%–7.17% overall performance improvement * Managing DRAM Latency Divergence in Irregular GPGPU Applications * [link](https://www.cs.utah.edu/~rajeev/pubs/sc14.pdf) 2014 * different requests from a warp are serviced together, or in quick succession, without interference from other warps * warp-aware memory controllers * boost performance by 10.1% * Graph Processing on GPUs: A Survey * [link](https://www.dcs.warwick.ac.uk/~liganghe/papers/ACM-Computing-Surveys-2017.pdf) 2018 * graph processing * data layout * memory access pattern * workload mapping * GPU programming * new research challenges and opportunities * Graph processing on hybrid systems * Graph processing on new GPU architecture * Dynamic graph processing on GPUs * the graph structure can be updated frequently in runtime * dynamically maintain balanced workload mapping with the rapid changes of graphs * Machine-learning applications * Anatomy of GPU Memory System for Multi-Application Execution * [link](https://www.cs.utexas.edu/users/skeckler/pubs/MEMSYS_2015_Anatomy.pdf) 2015 * study the memory system of GPUs in a concurrently executing **multi-application** environment * **L2-MPKI** and **attained bandwidth** are the two knobs that can be used to drive memory scheduling decisions for achieving better performance * Irregular Accesses Reorder Unit: Improving GPGPU Memory Coalescing for Graph-Based Workloads * [link](https://arxiv.org/pdf/2007.07131.pdf) * 1.33x and 13% improvement in performance and energy savings respectively * On-the-Fly Elimination of Dynamic Irregularities for GPU Computing * [link](https://dl.acm.org/doi/pdf/10.1145/1950365.1950408) * On-GPU Thread-Data Remapping for Branch Divergence Reduction * [link](https://dl.acm.org/doi/10.1145/3242089) * Nested Parallelism on GPU: Exploring Parallelization Templates for Irregular Loops and Recursive Computations * [link](https://ieeexplore.ieee.org/abstract/document/7349653) * use compiler to transform the original code to the template * Spare register aware prefetching for graph algorithms on GPUs * [link](https://ieeexplore.ieee.org/abstract/document/6835970) * use spare register to store the prefetch edge ### memory access divergence * DaCache: Memory Divergence-Aware GPU Cache Management ### pre-launch (inter-kernel) * BlockMaestro: Enabling Programmer-Transparent Task-based Execution in GPU Systems * [link](https://ieeexplore.ieee.org/document/9499869) * 用bipartite graph找出有dependency(locality)的TBs,並讓後面的TB pre-launch以減少launch time * 用編譯器就能解決,所以不用改code * **input-dependent** is not working ### inter-kernel locality * Inter-kernel reuse-aware thread block scheduling * group TBs * 下一個kernel的group與上一個kernel對齊 * reverse * work stealing,一次一個 ### intra-kernel locality * PAVER: Locality Graph-Based Thread Block Scheduling for GPUs * [link](https://dl.acm.org/doi/fullHtml/10.1145/3451164) 2021 * 用graph theory將TBs的locality都找出來 * 用graph partition將graph切成groups,每個group分給一個SM * work stealing,偷不只一個以維持locality * **input-dependent** is not working * [note](https://hackmd.io/q-vSikPLSdmNqHPz1GwQwA?view) * performance speedup by 29%, 49.1%, and 41.2% * Improving GPGPU Performance via Cache Locality Aware Thread Block Scheduling * [link](https://ieeexplore.ieee.org/abstract/document/7898501) * run time時才計算出與目前SM中的TBs最適合的TB作為候選人 * **input-dependent** is not working * Improving GPGPU resource utilization through alternative thread block scheduling * [link](https://ieeexplore.ieee.org/abstract/document/6835937?casa_token=jQrF9KO5vLMAAAAA:1_H9ANBV8mdo4iuC_Nz5bmcPPx4aKsjx4l15Y_1WnhdE8RBbm2hvXO6kdiSmRKZfK2NCJIoG_AU) * workload type * TB increase, performance increase * TB increase, performance increase then saturate * TB increase, performance decrease * TB increase, performance increase then decrease * core activity * ACTIVE * INACTIVE * Idle * Mem_stall * Core_stall * * SM裡的TBs數目會影響performance,最大未必會最好 * <img src="https://i.imgur.com/udazh1W.png" width="40%" height="40%" /> * consecutive CTAs are assigned to the same cores ### analyze data locality * LocalityGuru: A PTX Analyzer for Extracting Thread Block-level Locality in GPGPUs ### warp scheduler * A Novel Cooperative Warp and Thread Block Scheduling Technique for Improving the GPGPU Resource Utilization ### multiple streams scheduler * Performance Analysis of Thread Block Schedulers in GPGPU and Its Implications * Preemptive thread block scheduling with online structural runtime prediction for concurrent GPGPU kernels * Increasing GPU throughput using kernel interleaved thread block scheduling ### graph * Practical Optimal Cache Replacement for Graphs * 用transpose(CSC<->CSR)快速找到cache中下一次被存取時間最久的cache line * 適用traverse graph的應用(in/out) ## Time: 1/21/2022 ~ 1/26/2022 * goal * sssp_spmv, parboil: spmv, * node to warp mapping * data driven ## Time: 1/12/2022 ~ 1/20/2022 * progress * pagerank 5 graph testing * pagerank spmv * color max min ## Time: 10/21/2021 ~ 10/28/2021 * child thread block * change program? * warp formation * can do? * TB formation ## Time: 10/18/2021 ~ 10/25/2021 * 了解CSB * pagerank 問題 * 壓縮sparse matrix * cuSha ## Time: 10/14/2021 ~ 10/21/2021 * ~~color攤開第三層~~ * sssp跑NY * color跑大圖G3 * 改其他benchmark * ~~pagerank結果寫到spread sheet上~~ * pagerank問題 * atomicAdd ? * ITER拿掉 * 每個kernel看perfect memory / cache.nonflush * momory bound問題? * outcome * color-max * 有快一點 * memory access減少,但miss rate上升 * 攤開node value會更慢,memory access會再會再減少,但miss ra會再te * graph很balance * page-rank * 慢很多 * memory access減少,但miss rate上升 * graph很不balance ## Issue * race condition (sssp : min) * possible solution : atomic or synchronization * 兩層 for loop 不能攤開 ## Time: 10/7/2021 ~ 10/14/2021 * 每個kernel印出remap後的cycle * remap的跑在GPU上看看 (debug比較快) * 解決branch divergence(sort 每個vertex的edge數) * gpgpu-sim_simulations/benchmarks/src/cuda/rodinia/3.1/cuda/bfs/ ## Time: 9/24/2021 ~ 9/30/2021 看memory coaleasing有沒有出問題 memory bound是bound在哪邊 參考data reorder(no-coaleased) ## Time: 9/6/2021 - 9/12/2021 林孟賢:加上ideal cache的miss rate, 個別SM的cycle數(為了判斷 load balance), 每個kernel的miss rate 席致寧:group裡加上mst, 跑benchmark ## Time: 8/23/2021 - 9/5/2021 林孟賢:實做paver 席致寧:跑bechmark ## Time: 8/6/2021 - 8/12/2021 * embeddingbag 修改好embeddingbag cache access patern of embedding with 2 keys ``` -3221225472 57 => input(indices) -3221241536 1 -3221241472 7909 => weightFeat(weight) -3221241408 1 -3221241344 7909 => weightFeat(weight) -3221241152 1 -3221241088 7445 => weightFeat(weight) -3221241280 1 -3221241216 7445 => weightFeat(weight) -3221225536 1 -3221225600 57 => input(indices) -3221225664 1 -3221225728 57 -3221225792 1 -3221225856 57 -3221225920 1 -3221225984 57 ``` * 結論 * threads random access(跟input有關) weightFeat, 且locality會隨著dictionary增大而消失 * MIS * 印addr access number * shared/not shared histogram * 觀察 * [spread sheet](https://docs.google.com/spreadsheets/d/12SWUiwHGojaicbE4O3QcscHBK07e-__A8j6FICQJRYQ/edit#gid=1340093626 ) * 在shared和not shared的locality都很高的情況下,我們的cache分段方法沒有優勢。 * 如果跑在多個SM上能保留shared而讓,not shared的locality消失,那我們的方法或許會奏效。但我們的shared是根據inter kernel的locality去找的,在intra kernel是否有效還很難說 * 如果我們的方法(PCG)可以自由的hit, pending hit, sector miss, 那在4/6分之下可以達到和LRU差不多的結果 * Terminology * ideal: 只考慮某個cache line被**存取**幾次 * normal: 只考慮某個cache line被hit(包含第一次miss)幾次,不考慮pending hit和sector miss等 * shared: 可能表示**我們標的pc**或**高access次數的pc**所access到的cache line * not shared: 與shared相對 * both: shared與not shared都有access到的cache line * Outcome * ideal與LRU的比較 * kernel 2 * ideal, miss rate 0.243 <img src="https://i.imgur.com/l9ygFRx.png" width="50%" height="50%" /> * LRU, miss rate 0.287 <img src="https://i.imgur.com/lkn0XIW.png" width="50%" height="50%" /> * 結論 * LRU已經很接近ideal(total miss rate 0.54/0.48) * 相比於shared, not shared的cache line反倒是沒有很好的keep住 * bypass l1 cache * 比較慢 * high frequency ps has high priority to stay in cache(with LRU) * 比較慢 * ideal算法 * block addr要改成addr * sector miss要考慮進去 * miss rate算法 * tag_array算出來的是read的miss rate(剛好是我們要的) * 個別MISS或SCTOR_MISS與gpgpu-sim的有落差,但總和一樣(所以在我們的case下沒差) ## Time: 7/30/2021 - 8/5/2021 * cache切成兩部份 * shared(80%) * not shared(20%) * replacement policy * shared * LIFO * LRU * not shared * LRU * compared with ideal * cta scheduler reverse --- * cache line加上counter, 紀錄hit次數 * set l1 to tag_array * print cache access * s1 * 1 cta * 1 warp * sector miss要考慮 * future work * print cta access status ## Time: 7/22/2021 - 7/29/2021 * 將call/assign by reference/value實做出來 * 在vec-add上實做,結果符合預期 * ![](https://i.imgur.com/6h0zdO4.png) * ![](https://i.imgur.com/uN6IPIJ.png) ## Time: 7/19/2021 - 7/26/2021 * 7/16 * c的基本語法ok * bear沒有試成功,所以目前無法編譯需要make的cuda code * 7/19 * 開始做data member的部分 * 7/20 * data member的部分大致可以 * 發現member function有問題 * 7/21 * 修改data member的data structure以符合member function的操作 * 開始做member function * 7/22 * member function基本的case可以 * 發現member function在找data member時,若遇上inheritance會有問題 * 找到inherited的class * 待辦 * **declare** to **definition** (getDefinition) * 從全部視為pass by reference改成pass by reference/value * alias(變數的傳遞) * 考慮control flow(if, else等) ## Time: 7/12/2021 - 7/19/2021 ### 1. Successes Last Week <!-- * What you managed/plan to accomplish this week - hopefully in line with goals - if not that's okay too. --> * 席致寧 * 7/9 ~ 7/16 * [[筆記] build and run gpgpu-sim](https://hackmd.io/WsOKV8MmTfS1-Y5gyrS2UQ?view) * 7/16 ~ 7/23 * c_Kernel從constant memory改成global memory * for loop 改成用 multiple stream * [[筆記] streams & memory](https://hackmd.io/WTA8Vz_8Slyveitd7JDYMw?view) * 7/23 ~ 7/30 * [BuildMI()](https://llvm.org/docs/CodeGenerator.html#the-machineinstr-class) : extend machine instruction * [[筆記]memory](https://hackmd.io/MFf9C4AHRU2z6oy6X9DRXg) * [[筆記]LLVM](https://hackmd.io/HKv_OZvXSmWvkLXHTu6BaA) * 7/30 ~ 8/6 * [NVPTXInstrInfo.td](https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td) * 8/6 ~ 8/13 * compiling LLVM * 8/13 ~ 8/20 * [P-OPT: Practical Optimal Cache Replacement for Graph Analytics Architectures](https://hackmd.io/iCDyMqTNQ8a1DzwtSSV4Jg) * [Internal of LLVM](https://hackmd.io/bwlGi-ntTxCF1pTvB0N-YA) ### 2. Progress and Problems Last Week <!-- * What have you done last week ? * What problems encountered last week ? * What caused you to be slow on a particular task? What roadblocks did you encounter? --> * 跟**李睦樂**討論之後覺得理論上做的出來,但實做細節與clang API是否支援等現實層面的問題還在摸索中 * 限制條件為若有些kernel的parameter是runtime時才決定的 * 譬如:C = A+B的C與A在runtime時才得知是指到同一個obj,那我們在compile時就不會知道A的值是非read-only的 * 目前的想法為每一個變數與obj設置counter,當寫入時counter+1,最後看哪些變數符合條件 <font color= #DCDCDC> * 為每一個**變數**配置一個資料結構用來紀錄**write次數**, **類型(normal, array, pointer, reference)**, **指標(指到其他人的資料結構)** * 最後根據每一個變數**自己的資料結構**和**指到的資料結構**去判斷是否為constant * 超過2就非constant * 需要trace **call by value**, **call by reference**等實做方法(在找出哪些是我們要的變數上遇到了問題,因為 **=左右** 都可能存在不只一個變數) * 判斷 **= 右邊**的變數的level情況 * *: level-1 * &: level+1 * 二元運算子: 留下小的 * 用post order traversal的方法搭配stack找出level小的與 **= 左邊**的變數關聯 * 搭配children()用法 * http://web.mit.edu/freebsd/head/contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp </font> * write 指令包括 assign, compound assign, inc/dec * 被 write 的 variable 為 **=左邊** 的第一個variable(可能會有問題) <!--* 用bear -vvvv make這調指令以獲得compile_commands.json--> * 在sp和mst, **bear** 和 **compiledb** 無法取得compile_commands.json ### 3. Not Resolved Problems <!--* The checking list of problems you have not resolved yet.--> * 在找出哪些是我們要的變數上遇到了問題,因為 **=左右** 都可能存在不只一個變數 ### 4. Goals for next week * 席致寧 * shaer.cc (/src/gpgpu-sim) * issue_warp * 在TB裡面建立一個array,蒐集ld.global的address,找不同TB裡的交集 * warp_inst_t (/src/abstract_hardware_model.cc) * class warp_inst_t() * 加array來存address * memory_space_t (/src/abstract_hardware_model.cc) * is_global() * 林孟賢 * assign一律考慮為pass by reference,並run在不同cuda benchmark裡,確保cuda code可以run成功,並找出可能的問題 * vecadd: ok * ~/test/llvm-project-orig/llvm-project/build/bin/get-constant-variables test_case/vector-add.cu -- clang++ --cuda-gpu-arch=sm_75 -L /usr/local/cuda/lib64 -lcudart_static -ldl -lrt -pthread * ![](https://i.imgur.com/0vceiiJ.png) * pathfinder: * ~/test/llvm-project-orig/llvm-project/build/bin/get-constant-variables pathfinder.cu -- clang++ --cuda-gpu-arch=sm_75 -L /usr/local/cuda/lib64 -lcudart_static -ldl -lrt -pthread * ![](https://i.imgur.com/h0Owq9L.png)