nb_kernel200_ia64_double.s
来自「最著名最快的分子模拟软件」· S 代码 · 共 930 行 · 第 1/2 页
S
930 行
} { .mmi shladd posPtr = II3, 3, POSITION shladd FActII = II3, 3, FACTION shladd shiftVPtr = IS3, 3, SHIFTVEC } ;;// THREAD PROLOGUE 6 { .mmi ld4 jnr = [jjnrPtr], 4 (pCont) ld4 IS = [shiftPtr], 4 nop 0x0 } { .mmi (pCont) ld4 II = [iinrPtr], 4 nop 0x0 nop 0x0 } ;;// 12 bundles in thread prologue - still alignedouterLoop: // At this point in the outer loop, the following values are ready // // FActII Pointer to FACTION XYZ for II // FShiftIS Pointer to FSHIFT XYZ for IS // shiftVPtr Pointer to current shift XYZ values // posPtr Pointer to current XYZ position // chargePtr Pointer to current atom charge // ggid Index for Vc array // jjnr Pointer to next neighbor index // jnr Current jnr value // NJ0, NJ1 Bounds of current neighbor list // // Load up all the floating-point values (yes, McKinley can do 4 FP loads // per cycle) and initialize the loop counters and predicates. Compute // the initial position <x, y, z> and charge. If this isn't the last time // through the loop, start loading the next value for NJ1 - we already // moved the previous NJ1 -> NJ0.// OUTER PROLOGUE 1 { .mmf ldfd shX = [shiftVPtr], 8 ldfd PosX = [posPtr], 8 mov FIX = f0 } { .mmf ldfd FActIX = [FActII], 8 ldfd FShiftX = [FShiftIS], 8 mov FIY = f0 } ;;// OUTER PROLOGUE 2 { .mmf ldfd shY = [shiftVPtr], 8 ldfd PosY = [posPtr], 8 mov FIZ = f0 } { .mmi ldfd FActIY = [FActII], 8 ldfd FShiftY = [FShiftIS], 8 shladd VCPtr = ggid, 3, VC } ;;// OUTER PROLOGUE 3 { .mmi ldfd shZ = [shiftVPtr] ldfd PosZ = [posPtr] sub InnerCnt = NJ1, NJ0, 1 } { .mmi ldfd FActIZ = [FActII], -16 ldfd FShiftZ = [FShiftIS], -16 mov NJ0 = NJ1 } ;;// OUTER PROLOGUE 4 { .mmf ldfd ICharge = [chargePtr] ldfd VCTotal = [VCPtr] fadd IX = shX, PosX } ;;// OUTER PROLOGUE 5 { .mfi add NN0 = 1, NN0 fadd IY = shY, PosY // This may seem strange, but we set the first stage of the // pipe to execute this way because setting pr.rot doesn't take // into account how much the predicates have rotated. If this is // the first time through, we cleared all the pipeline predicates // in the initialization. If not, flushing the pipeline set all // the pipeline predicates to 0 cmp.eq pPipe[0], p0 = zero, zero } ;;// OUTER PROLOGUE 6 { .mfi cmp.lt pCont, pDone = NN0, NN1 fadd IZ = shZ, PosZ mov ar.lc = InnerCnt } ;;// OUTER PROLOGUE 7 { .mfi (pCont) ld4 NJ1 = [jindexPtr], 4 fmpy IQ = ICharge, Facel mov ar.ec = PIPE_DEPTH } ;;// 10 bundles in outer loop - still aligned. // The inner loop is a 6-stage pipeline. The serial sequence of float ops // is folded into a 12-cycle loop (12 * 2 = 24 float ops), then divided // into 5 stages.innerLoop:// INNER LOOP 1 { .mfi (pPipe[0]) shladd chargePtr = jnr, 3, CHARGE (pPipe[1]) fsub DX[1] = IX, DX[1] (pPipe[0]) shladd jnr3 = jnr, 1, jnr } // We march through jjnr[] sequentially, so it's usually a good idea // to preload the next value. However, we don't want to do this if // (1) we're in the epilogue or (2) this is the last time through and // there are no more atoms to inspect. Thus, we keep track of the loop // trip and use the logic below to see if we should load ahead .pred.rel "mutex", pCont, pDone { .mfi (pCont) cmp.ge pJJNR, p0 = InnerCnt, zero (pPipe[2]) frsqrta RInv[0], p0 = RSqr[1] (pDone) cmp.gt pJJNR, p0 = InnerCnt, zero } ;;// INNER LOOP 2 { .mfi (pJJNR) ld4 jnr = [jjnrPtr], 4 (pPipe[1]) fsub DY[1] = IY, DY[1] (pPipe[0]) add Ninner = 1, Ninner } { .mfi (pPipe[0]) shladd posPtr = jnr3, 3, POSITION (pPipe[3]) fma RInv[1] = RInvU[1], RInvT[1], RInv[1] (pPipe[0]) shladd FActPtr[0] = jnr3, 3, FACTION } ;;// INNER LOOP 3 { .mfi (pPipe[0]) ldfd JX = [posPtr], 8 (pPipe[1]) fsub DZ[1] = IZ, DZ[1] (pPipe[0]) add InnerCnt = -1, InnerCnt } { .mfi nop 0x0 (pPipe[4]) fsub KRSqr[2] = KRSqr[2], Crf nop 0x0 } ;;// INNER LOOP 4 { .mfi (pPipe[0]) ldfd JY = [posPtr], 8 (pPipe[4]) fmpy RInv2[0] = RInv[2], RInv[2] (pJJNR) add jjnrPtr = JJNR_PREFETCH_DISTANCE, jjnrPtr } { .mfi nop 0x0 (pPipe[5]) fnma FActX[5] = FScalar[2], DX[5], FActX[5] nop 0x0 } ;; // INNER LOOP 5 { .mfi (pPipe[0]) ldfd JZ = [posPtr], 8 (pPipe[1]) fmpy RSqr[0] = DX[1], DX[1] nop 0x0 } { .mfi nop 0x0 (pPipe[2]) fmpy RInvErr[0] = RInv[0], RSqr[1] nop 0x0 } ;;// INNER LOOP 6 { .mfi (pPipe[0]) ldfd FActX[0] = [FActPtr[0]], 8 (pPipe[3]) fmpy RInvErr[1] = RInv[1], RSqr[2] nop 0x0 } { .mfi (pJJNR) lfetch.nta [jjnrPtr] (pPipe[5]) fnma FActY[5] = FScalar[2], DY[5], FActY[5] nop 0x0 } ;;// INNER LOOP 7 { .mfi (pPipe[0]) ldfd FActY[0] = [FActPtr[0]], 8 (pPipe[4]) fadd KRSqr[2] = RInv[2], KRSqr[2] (pJJNR) add jjnrPtr = -JJNR_PREFETCH_DISTANCE, jjnrPtr } { .mfi nop 0x0 (pPipe[5]) fnma FActZ[5] = FScalar[2], DZ[5], FActZ[5] nop 0x0 } ;;// INNER LOOP 8 { .mfi (pPipe[0]) ldfd FActZ[0] = [FActPtr[0]], -16 (pPipe[5]) fma FIX = DX[5], FScalar[2], FIX nop 0x0 } { .mfi nop 0x0 (pPipe[3]) fmpy RInvT[1] = RInv[1], fHALF nop 0x0 } ;;// INNER LOOP 9 { .mfi (pPipe[0]) ldfd QCharge = [chargePtr] (pPipe[1]) fma RSqr[0] = DY[1], DY[1], RSqr[0] nop 0x0 } { .mfi nop 0x0 (pPipe[2]) fnma RInvErr[0] = RInvErr[0], RInv[0], fOne nop 0x0 } ;;// INNER LOOP 10 { .mfi nop 0x0 (pPipe[3]) fnma RInvErr[1] = RInvErr[1], RInv[1], fOne nop 0x0 } { .mfi nop 0x0 (pPipe[5]) fma FIY = DY[5], FScalar[2], FIY nop 0x0 } ;;// INNER LOOP 11 { .mfi nop 0x0 (pPipe[4]) fmpy RInv2[0] = Charge[4], RInv2[0] nop 0x0 } { .mfi nop 0x0 (pPipe[2]) fmpy Charge[2] = Charge[2], IQ nop 0x0 } ;;// INNER LOOP 12 { .mfi nop 0x0 (pPipe[3]) fnma FScalar[0] = fTWO, KRSqr[1], RInv[1] nop 0x0 } { .mfi nop 0x0 (pPipe[5]) fma FIZ = DZ[5], FScalar[2], FIZ nop 0x0 } ;;// INNER LOOP 13 { .mfi nop 0x0 (pPipe[1]) fma RSqr[0] = DZ[1], DZ[1], RSqr[0] nop 0x0 } { .mfb nop 0x0 (pPipe[2]) fmpy RInvU[0] = RInv[0], RInvErr[0] nop 0x0 } ;;// INNER LOOP 14 { .mfi (pPipe[5]) stfd [FActPtr[5]] = FActX[5], 8 (pPipe[3]) fma RInv[1] = RInvT[1], RInvErr[1], RInv[1] nop 0x0 } { .mfi nop 0x0 (pPipe[2]) fma RInvT[0] = RInvErr[0], f3_8, fHALF nop 0x0 } ;;// INNER LOOP 15 { .mfi (pPipe[5]) stfd [FActPtr[5]] = FActY[5], 8 (pPipe[2]) fmpy KRSqr[0] = RSqr[1], Krf nop 0x0 } { .mfi nop 0x0 (pPipe[4]) fmpy FScalar[1] = FScalar[1], RInv2[0] nop 0x0 } ;;// INNER LOOP 16 { .mfi (pPipe[5]) stfd [FActPtr[5]] = FActZ[5] (pPipe[4]) fma VCTotal = Charge[4], KRSqr[2], VCTotal nop 0x0 } { .mfb nop 0x0 nop 0x0 br.ctop.sptk.many innerLoop } ;; // End of modulo-scheduled inner loop // Having finshed the loop, we now compute various quantities to // store. In paralllel, start computing computing some of the values // for the next loop trip, if we're going there.// OUTER EPILOGUE 1 { .mfi nop 0x0 nop 0x0 (pCont) shladd II3 = II, 1, II } { .mfi (pCont) shladd chargePtr = II, 3, CHARGE nop 0x0 (pCont) shladd IS3 = IS, 1, IS } ;;// OUTER EPILOGUE 2 { .mfi (pCont) ld4 II = [iinrPtr] ,4 fadd FActIX = FActIX, FIX nop 0x0 } { .mfi (pCont) ld4 IS = [shiftPtr], 4 fadd FShiftX = FShiftX, FIX add Nouter = 1, Nouter } ;;// OUTER EPILOGUE 3 { .mfi nop 0x0 fadd FActIY = FActIY, FIY (pCont) shladd shiftVPtr = IS3, 3, SHIFTVEC } { .mfi nop 0x0 fadd FShiftY = FShiftY, FIY (pCont) shladd posPtr = II3, 3, POSITION } ;;// OUTER EPILOGUE 4 { .mfi nop 0x0 fadd FActIZ = FActIZ, FIZ nop 0x0 } { .mfi nop 0x0 fadd FShiftZ = FShiftZ, FIZ nop 0x0 } ;;// OUTER EPILOGUE 5 { .mmi stfd [FActII] = FActIX, 8 stfd [FShiftIS] = FShiftX, 8 nop 0x0 } { .mmi stfd [VCPtr] = VCTotal (pCont) ld4 ggid = [gidPtr], 4 nop 0x0 } ;;// OUTER EPILOGUE 6 { .mmi stfd [FActII] = FActIY, 8 stfd [FShiftIS] = FShiftY, 8 nop 0x0 } ;;// OUTER EPILOGUE 7 { .mfi stfd [FActII] = FActIZ nop 0x0 (pCont) shladd FActII = II3, 3, FACTION } { .mib stfd [FShiftIS] = FShiftZ (pCont) shladd FShiftIS = IS3, 3, FSHIFT (pCont) br.cond.sptk.many outerLoop } ;; // Finish if this was the last chunk, or do another thread-loop iteration// THREAD EPILOGUE 1 { .mib nop 0x0 nop 0x0 (pMore) br.cond.sptk.many threadLoop } ;; // Ready to exit - restore the floating-point registers we saved, the // loop counter, and the predicates, then we're done. Note that the // stack pointer has the address of the last saved FP register.finish:// EXIT 1 { .mmi mov fillP0 = sp add fillP1 = 16, sp nop 0x0 } { .mmi st4 [OuterIter] = Nouter st4 [InnerIter] = Ninner nop 0x0 };;// EXIT 2 { .mmi ldf.fill fs10 = [fillP0], 32 ldf.fill fs9 = [fillP1], 32 nop 0x0 } ;;// EXIT 2 { .mmi ldf.fill fs8 = [fillP0], 32 ldf.fill fs7 = [fillP1], 32 mov ar.lc = LCSave } ;;// EXIT 3 { .mmi ldf.fill fs6 = [fillP0], 32 ldf.fill fs5 = [fillP1], 32 mov pr = PRSave, 0x1ffff } ;;// EXIT 4 { .mmi ldf.fill fs4 = [fillP0], 32 ldf.fill fs3 = [fillP1], 32 add sp = 10 * 16, sp } ;;// EXIT 5 { .mmi ldf.fill fs2 = [fillP0], 32 ldf.fill fs1 = [fillP1], 32 nop 0x0 } ;;// EXIT 6 { .mfb ldf.fill fs0 = [fillP0] nop 0x0 br.ret.sptk.few rp } ;; .endp nb_kernel200_ia64_double
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?