Changeset 6084


Ignore:
Timestamp:
Jun 12, 2018, 1:30:29 PM (8 days ago)
Author:
xwa163
Message:

Use scatter for match copy in LZ4ParallelByteStreamAIOKernel

Location:
icGREP/icgrep-devel/icgrep/kernels/lz4
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/kernels/lz4/lz4_parallel_bytestream_aio.cpp

    r6082 r6084  
    4444                                           Binding{b->getInt64Ty(), "tempTimes"},
    4545                                           Binding{b->getIntNTy(SIMD_WIDTH), "outputPos"},
     46                                           Binding{b->getBitBlockType(), "placeholder"},
    4647
    4748                                   }), mEnableGather(enableGather), mEnableScatter(enableScatter), mOutputBlockSize(outputBlockSize) {
     
    632633    }
    633634
     635    void LZ4ParallelByteStreamAioKernel::generateSimdMatchCopyByScatter(const std::unique_ptr<KernelBuilder> &b, llvm::Value* matchOffsetVec, llvm::Value* matchLengthVec, llvm::Value* outputPosVec) {
     636        // ---- EntryBlock
     637        BasicBlock* entryBlock = b->GetInsertBlock();
     638        BasicBlock* exitBlock = b->CreateBasicBlock("exitBlock");
     639        BasicBlock* i64MatchCopyBlock = b->CreateBasicBlock("i64MatchCopyBlock");
     640        BasicBlock* i8MatchCopyBlock = b->CreateBasicBlock("i8MatchCopyBlock");
     641
     642        llvm::Value* initCopiedLength = ConstantVector::getNullValue(matchLengthVec->getType());
     643
     644//        Value* inputBasePtr = b->CreatePointerCast(b->getRawInputPointer("byteStream", b->getSize(0)), b->getInt8PtrTy());
     645        Value* outputBasePtr = b->CreatePointerCast(b->getRawOutputPointer("outputStream", b->getSize(0)), b->getInt8PtrTy());
     646
     647        Value* outputCapacity = b->getCapacity("outputStream");
     648        Value* outputPosRemVec = b->simd_and(outputPosVec, b->simd_fill(SIMD_WIDTH, b->CreateNot(b->CreateNeg(outputCapacity))));
     649        Value* outputPosRemBlockSizeVec = b->simd_and(outputPosVec, b->simd_fill(SIMD_WIDTH, b->CreateNot(b->CreateNeg(b->getIntN(SIMD_WIDTH, mOutputBlockSize)))));
     650        Value* remainingBlockSizeVec = b->simd_sub(SIMD_WIDTH, b->simd_fill(SIMD_WIDTH, b->getIntN(SIMD_WIDTH, mOutputBlockSize)), outputPosRemBlockSizeVec);
     651
     652        Value* possibleExceedBuffer = b->simd_uge(SIMD_WIDTH, b->simd_add(SIMD_WIDTH, matchLengthVec, b->simd_fill(SIMD_WIDTH, b->getIntN(SIMD_WIDTH, 8))), remainingBlockSizeVec);
     653        // true ffff, false 0000
     654
     655        // TODO handle matchLengthVec == 0
     656
     657        b->CreateUnlikelyCondBr(
     658                b->CreateICmpNE(b->CreateBitCast(possibleExceedBuffer, b->getIntNTy(b->getBitBlockWidth())), b->getIntN(b->getBitBlockWidth(), 0)),
     659                i8MatchCopyBlock,
     660                i64MatchCopyBlock
     661        );
     662
     663        // ---- i8MatchCopyBlock
     664        b->SetInsertPoint(i8MatchCopyBlock);
     665        this->generateSimdSequentialMatchCopy(b, matchOffsetVec, matchLengthVec, outputPosVec);
     666        b->CreateBr(exitBlock);
     667
     668        // ---- i64MatchCopyBlock
     669        b->SetInsertPoint(i64MatchCopyBlock);
     670
     671        BasicBlock* i64MatchCopyConBlock = b->CreateBasicBlock("i64MatchCopyConBlock");
     672        BasicBlock* i64MatchCopyBodyBlock = b->CreateBasicBlock("i64MatchCopyBodyBlock");
     673
     674        b->CreateBr(i64MatchCopyConBlock);
     675
     676        // ---- i64MatchCopyConBlock
     677        b->SetInsertPoint(i64MatchCopyConBlock);
     678        PHINode* phiCopiedLength = b->CreatePHI(initCopiedLength->getType(), 2);
     679        phiCopiedLength->addIncoming(initCopiedLength, i64MatchCopyBlock);
     680
     681        Value* shouldCopiedBitBlock = b->simd_ult(SIMD_WIDTH, phiCopiedLength, matchLengthVec);
     682//        b->CallPrintRegister("phiCopiedLength", phiCopiedLength);
     683//        b->CallPrintRegister("literalLengthVec", literalLengthVec);
     684//        b->CallPrintRegister("shouldCopiedBitBlock", shouldCopiedBitBlock);
     685        Value* shouldCopiedI1 = b->CreateICmpNE(
     686                b->CreateBitCast(shouldCopiedBitBlock, b->getIntNTy(b->getBitBlockWidth())),
     687                b->getIntN(b->getBitBlockWidth(), 0)
     688        );
     689
     690
     691        b->CreateCondBr(shouldCopiedI1, i64MatchCopyBodyBlock, exitBlock);
     692
     693        // ---- i64MatchCopyBodyBlock
     694        b->SetInsertPoint(i64MatchCopyBodyBlock);
     695        Value* currentOutputPosVec = b->simd_add(SIMD_WIDTH, outputPosRemVec, phiCopiedLength);
     696        Value* copyFromPosVec = b->simd_sub(SIMD_WIDTH, currentOutputPosVec, matchOffsetVec);
     697
     698        Value* literalData = this->simdFetchI64DataByGather(b, outputBasePtr, copyFromPosVec, shouldCopiedBitBlock);
     699
     700        this->simdPutData(
     701                b,
     702                outputBasePtr,
     703                currentOutputPosVec,
     704                literalData,
     705                shouldCopiedBitBlock
     706        );
     707        phiCopiedLength->addIncoming(
     708                b->simd_add(
     709                        SIMD_WIDTH,
     710                        phiCopiedLength,
     711                        b->simd_and(
     712                                b->simd_umin(SIMD_WIDTH, matchOffsetVec, b->simd_fill(SIMD_WIDTH, b->getIntN(SIMD_WIDTH, 8))),
     713                                shouldCopiedBitBlock
     714                        )
     715
     716                ),
     717                b->GetInsertBlock()
     718        );
     719
     720        b->CreateBr(i64MatchCopyConBlock);
     721        b->SetInsertPoint(exitBlock);
     722
     723    }
     724
    634725    void LZ4ParallelByteStreamAioKernel::generateSimdSequentialMatchCopy(const std::unique_ptr<KernelBuilder> &b, llvm::Value* matchOffsetVec, llvm::Value* matchLengthVec, llvm::Value* outputPosVec) {
    635 
    636726        // Constant
    637727        Constant * SIZE_8 = b->getSize(8);
     
    689779
    690780    void LZ4ParallelByteStreamAioKernel::handleSimdMatchCopy(const std::unique_ptr<KernelBuilder> &b, llvm::Value* matchOffsetVec, llvm::Value* matchLengthVec, llvm::Value* outputPosVec) {
    691         this->generateSimdSequentialMatchCopy(b, matchOffsetVec, matchLengthVec, outputPosVec);
     781        if (AVX512BW_available() && mEnableScatter) {
     782            this->generateSimdMatchCopyByScatter(b, matchOffsetVec, matchLengthVec, outputPosVec);
     783        } else {
     784            this->generateSimdSequentialMatchCopy(b, matchOffsetVec, matchLengthVec, outputPosVec);
     785        }
    692786    }
    693787
     
    11141208        if (AVX512BW_available()) {
    11151209            // AVX512 gather use i8 mask
    1116             //declare <8 x double> @llvm.x86.avx512.gather.dpq.512(<8 x i64>, i8*, <8 x i32>, i8, i32) #1
     1210            //declare <8 x int> @llvm.x86.avx512.gather.dpq.512(<8 x i64>, i8*, <8 x i32>, i8, i32) #1
    11171211            Function *gatherFunc512 = Intrinsic::getDeclaration(b->getModule(), Intrinsic::x86_avx512_gather_dpq_512);
    11181212            return b->CreateCall(
     
    11471241                                                                     llvm::Value *basePtr, llvm::Value *offsetVec,
    11481242                                                                     llvm::Value *maskVec) {
     1243        Value* placeHolderPtr = b->CreatePointerCast(b->getScalarFieldPtr("placeholder"), basePtr->getType());
     1244
    11491245        Value* retVec = ConstantVector::getNullValue(b->getBitBlockType());
    11501246
     
    11521248            Value* mask = b->CreateExtractElement(maskVec, i);
    11531249            Value* shouldLoad = b->CreateICmpNE(mask, b->getInt64(0));
    1154 //            Value* loadPtr = b->CreateSelect(shouldLoad, b->CreateGEP(basePtr, b->CreateExtractElement(offsetVec, i)), basePtr);
    1155             Value* loadPtr = b->CreateGEP(basePtr, b->CreateExtractElement(offsetVec, i));
     1250            Value* loadPtr = b->CreateSelect(shouldLoad, b->CreateGEP(basePtr, b->CreateExtractElement(offsetVec, i)), placeHolderPtr);
     1251//            Value* loadPtr = b->CreateGEP(basePtr, b->CreateExtractElement(offsetVec, i));
    11561252            Value* loadValue = b->CreateZExt(b->CreateLoad(b->CreatePointerCast(loadPtr, b->getInt64Ty()->getPointerTo())), b->getInt64Ty());
    11571253            Value* finalValue = b->CreateSelect(shouldLoad, loadValue, b->getInt64(0));
  • icGREP/icgrep-devel/icgrep/kernels/lz4/lz4_parallel_bytestream_aio.h

    r6081 r6084  
    7171        void handleSimdMatchCopy(const std::unique_ptr<KernelBuilder> &b, llvm::Value* matchOffsetVec, llvm::Value* matchLengthVec, llvm::Value* outputPosVec);
    7272        void generateSimdSequentialMatchCopy(const std::unique_ptr<KernelBuilder> &b, llvm::Value* matchOffsetVec, llvm::Value* matchLengthVec, llvm::Value* outputPosVec);
     73        void generateSimdMatchCopyByScatter(const std::unique_ptr<KernelBuilder> &b, llvm::Value* matchOffsetVec, llvm::Value* matchLengthVec, llvm::Value* outputPosVec);
    7374
    7475        void handleLiteralCopy(const std::unique_ptr<KernelBuilder> &b, llvm::Value* literalStart, llvm::Value* literalLength, llvm::Value* outputPos);
Note: See TracChangeset for help on using the changeset viewer.