Ignore:
Timestamp:
Dec 15, 2018, 3:43:59 PM (4 months ago)
Author:
nmedfort
Message:

Re-enabled segment pipeline parallelism; moved logical segment number into pipeline kernel.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/kernels/pipeline/core_logic.hpp

    r6233 r6237  
    66
    77/** ------------------------------------------------------------------------------------------------------------- *
    8  * @brief addInternalKernelProperties
    9  ** ------------------------------------------------------------------------------------------------------------- */
    10 inline void PipelineCompiler::addInternalKernelProperties(BuilderRef b) {
     8 * @brief addPipelineKernelProperties
     9 ** ------------------------------------------------------------------------------------------------------------- */
     10inline void PipelineCompiler::addPipelineKernelProperties(BuilderRef b) {
    1111    initializePopCounts();
    1212    const auto numOfKernels = mPipeline.size();
    1313    b->setKernel(mPipelineKernel);
    14     IntegerType * const boolTy = b->getInt1Ty();
    1514    for (unsigned i = 0; i < numOfKernels; ++i) {
    16         // TODO: prove two termination signals can be fused into a single counter?
    17         const auto prefix = makeKernelName(i);
    18         mPipelineKernel->addInternalScalar(boolTy, prefix + TERMINATION_SIGNAL);
     15        addInternalKernelProperties(b, i);
    1916        addBufferHandlesToPipelineKernel(b, i);
    2017        addPopCountScalarsToPipelineKernel(b, i);
    2118    }
    2219    b->setKernel(mPipelineKernel);
     20}
     21
     22//const static std::string PROCESSED_ITEM_COUNT_SUFFIX = "_processedItemCount";
     23//const static std::string PRODUCED_ITEM_COUNT_SUFFIX = "_producedItemCount";
     24// const static std::string NON_DEFERRED_ITEM_COUNT_SUFFIX = "_nonDeferredItemCount";
     25// const static std::string LOGICAL_SEGMENT_NO_SCALAR = "segmentNo";
     26
     27/** ------------------------------------------------------------------------------------------------------------- *
     28 * @brief addInternalKernelProperties
     29 ** ------------------------------------------------------------------------------------------------------------- */
     30inline void PipelineCompiler::addInternalKernelProperties(BuilderRef b, const unsigned kernelIndex) {
     31//    Kernel * const kernel = mPipeline[kernelIndex];
     32    IntegerType * const sizeTy = b->getSizeTy();
     33
     34    const auto name = makeKernelName(kernelIndex);
     35    // TODO: prove two termination signals can be fused into a single counter?
     36    mPipelineKernel->addInternalScalar(b->getInt1Ty(), name + TERMINATION_SIGNAL);
     37    // TODO: non deferred item count for fixed rates could be calculated from seg no.
     38    mPipelineKernel->addInternalScalar(sizeTy, name + LOGICAL_SEGMENT_NO_SCALAR);
     39
     40//    const auto numOfInputs = kernel->getNumOfStreamInputs();
     41//    for (unsigned i = 0; i < numOfInputs; i++) {
     42//        const Binding & input = kernel->getInputStreamSetBinding(i);
     43//        const auto prefix = makeBufferName(kernelIndex, input);
     44//        mPipelineKernel->addInternalScalar(sizeTy, prefix + PROCESSED_ITEM_COUNT_SUFFIX);
     45//        if (input.isDeferred()) {
     46//            mPipelineKernel->addInternalScalar(sizeTy, prefix + NON_DEFERRED_ITEM_COUNT_SUFFIX);
     47//        }
     48//    }
     49
     50//    const auto numOfOutputs = kernel->getNumOfStreamOutputs();
     51//    for (unsigned i = 0; i < numOfOutputs; i++) {
     52//        const Binding & output = kernel->getOutputStreamSetBinding(i);
     53//        const auto prefix = makeBufferName(kernelIndex, output);
     54//        mPipelineKernel->addInternalScalar(sizeTy, prefix + PRODUCED_ITEM_COUNT_SUFFIX);
     55//        if (output.isDeferred()) {
     56//            mPipelineKernel->addInternalScalar(sizeTy, prefix + NON_DEFERRED_ITEM_COUNT_SUFFIX);
     57//        }
     58//    }
     59
    2360}
    2461
     
    299336
    300337    readFinalProducedItemCounts(b);
    301     releaseCurrentSegment(b);
    302338    updateOptionalCycleCounter(b);
    303339
     
    305341}
    306342
    307 /** ------------------------------------------------------------------------------------------------------------- *
    308  * @brief wait
     343// Synchronization actions for executing a kernel for a particular logical segment.
     344
     345// Before the segment is processed, CreateAtomicLoadAcquire must be used to load
     346// the segment number of the kernel state to ensure that the previous segment is
     347// complete (by checking that the acquired segment number is equal to the desired segment
     348// number).
     349
     350// After all segment processing actions for the kernel are complete, and any necessary
     351// data has been extracted from the kernel for further pipeline processing, the
     352// segment number must be incremented and stored using CreateAtomicStoreRelease.
     353
     354/** ------------------------------------------------------------------------------------------------------------- *
     355 * @brief synchronize
    309356 ** ------------------------------------------------------------------------------------------------------------- */
    310357void PipelineCompiler::synchronize(BuilderRef b) {
    311358
    312     const auto kernelName = makeKernelName(mKernelIndex);
    313 
    314     BasicBlock * const kernelWait = b->CreateBasicBlock(kernelName + "Wait", mPipelineEnd);
     359    const auto prefix = makeKernelName(mKernelIndex);
     360    b->setKernel(mPipelineKernel);
     361    BasicBlock * const kernelWait = b->CreateBasicBlock(prefix + "Wait", mPipelineEnd);
    315362    b->CreateBr(kernelWait);
    316363
    317364    b->SetInsertPoint(kernelWait);
    318     const Kernel * waitingOn = mKernel;
    319     if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::SerializeThreads))) {
    320         waitingOn = mPipeline.back();
    321     }
    322     b->setKernel(waitingOn);
    323     Value * const processedSegmentCount = b->acquireLogicalSegmentNo();
     365    const auto serialize = codegen::DebugOptionIsSet(codegen::SerializeThreads);
     366    const unsigned waitingOnIdx = serialize ? mPipeline.size() - 1 : mKernelIndex;
     367    const auto waitingOn = makeKernelName(waitingOnIdx);
     368    Value * const waitingOnPtr = b->getScalarFieldPtr(waitingOn + LOGICAL_SEGMENT_NO_SCALAR);
     369    Value * const processedSegmentCount = b->CreateAtomicLoadAcquire(waitingOnPtr);
    324370    assert (processedSegmentCount->getType() == mSegNo->getType());
    325371    Value * const ready = b->CreateICmpEQ(mSegNo, processedSegmentCount);
    326372
    327     BasicBlock * const kernelCheck = b->CreateBasicBlock(kernelName + "Check", mPipelineEnd);
     373    BasicBlock * const kernelCheck = b->CreateBasicBlock(prefix + "Check", mPipelineEnd);
    328374    b->CreateCondBr(ready, kernelCheck, kernelWait);
    329375
     
    332378}
    333379
     380/** ------------------------------------------------------------------------------------------------------------- *
     381 * @brief releaseCurrentSegment
     382 ** ------------------------------------------------------------------------------------------------------------- */
     383inline void PipelineCompiler::releaseCurrentSegment(BuilderRef b) {
     384    b->setKernel(mPipelineKernel);
     385    Value * const nextSegNo = b->CreateAdd(mSegNo, b->getSize(1));
     386    const auto prefix = makeKernelName(mKernelIndex);
     387    Value * const waitingOnPtr = b->getScalarFieldPtr(prefix + LOGICAL_SEGMENT_NO_SCALAR);
     388    b->CreateAtomicStoreRelease(nextSegNo, waitingOnPtr);
     389}
    334390
    335391/** ------------------------------------------------------------------------------------------------------------- *
     
    525581}
    526582
    527 /** ------------------------------------------------------------------------------------------------------------- *
    528  * @brief releaseCurrentSegment
    529  ** ------------------------------------------------------------------------------------------------------------- */
    530 inline void PipelineCompiler::releaseCurrentSegment(BuilderRef b) {
    531     Value * const nextSegNo = b->CreateAdd(mSegNo, b->getSize(1));
    532     if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableMProtect))) {
    533         b->CreateMProtect(mKernel->getHandle(), CBuilder::Protect::WRITE);
    534     }
    535     b->releaseLogicalSegmentNo(nextSegNo);
    536     if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableMProtect))) {
    537         b->CreateMProtect(mKernel->getHandle(), CBuilder::Protect::READ);
    538     }
    539 }
    540 
    541 }
     583}
Note: See TracChangeset for help on using the changeset viewer.