Changeset 5253


Ignore:
Timestamp:
Jan 10, 2017, 3:55:08 PM (11 months ago)
Author:
cameron
Message:

Termination signal checking and doSegment/final segment separation for segment-pipeline parallel thread functions.

File:
1 edited

Legend:

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

    r5252 r5253  
    8181    BasicBlock * segmentLoop = BasicBlock::Create(iBuilder->getContext(), "segmentLoop", threadFunc, 0);
    8282    BasicBlock * exitThreadBlock = BasicBlock::Create(iBuilder->getContext(), "exitThread", threadFunc, 0);
     83   
    8384    std::vector<BasicBlock *> segmentWait;
    8485    std::vector<BasicBlock *> segmentLoopBody;
    85     for (unsigned i = 0; i < kernels.size(); i++) {
    86         segmentWait.push_back(BasicBlock::Create(iBuilder->getContext(), "segmentWait"+std::to_string(i), threadFunc, 0));
    87         segmentLoopBody.push_back(BasicBlock::Create(iBuilder->getContext(), "segmentWait"+std::to_string(i), threadFunc, 0));
    88     }
     86    std::vector<BasicBlock *> partialSegmentWait;
     87    std::vector<BasicBlock *> partialSegmentLoopBody;
     88    bool terminationSignalEncountered = false;
     89    for (unsigned i = 0; i < kernels.size(); i++) {
     90        std::string kname = kernels[i]->getName();
     91        segmentWait.push_back(BasicBlock::Create(iBuilder->getContext(), kname + "Wait", threadFunc, 0));
     92        segmentLoopBody.push_back(BasicBlock::Create(iBuilder->getContext(), "do_" + kname, threadFunc, 0));
     93        if (terminationSignalEncountered) {
     94            partialSegmentWait.push_back(BasicBlock::Create(iBuilder->getContext(), kname + "WaitFinal", threadFunc, 0));
     95            partialSegmentLoopBody.push_back(BasicBlock::Create(iBuilder->getContext(), "finish_" + kname, threadFunc, 0));
     96        }
     97        else {
     98            partialSegmentWait.push_back(nullptr);
     99            partialSegmentLoopBody.push_back(nullptr);
     100            terminationSignalEncountered = kernels[i]->hasNoTerminateAttribute() == false;
     101        }
     102    }
     103    segmentWait.push_back(segmentLoop); // If the last kernel does not terminate, loop back.
     104    partialSegmentWait.push_back(exitThreadBlock); // If the last kernel does terminate, we're done.
    89105
    90106    iBuilder->SetInsertPoint(entryBlock);
     
    116132
    117133        iBuilder->SetInsertPoint(segmentLoopBody[i]);
     134        if (i == last_kernel) {
     135            segNo->addIncoming(iBuilder->CreateAdd(segNo, ConstantInt::get(size_ty, threadNum)), segmentLoopBody[last_kernel]);
     136        }
    118137        kernels[i]->createDoSegmentCall(instancePtrs[i], segmentBlocks);
    119         // Must be the last action, for synchronization.
    120         kernels[i]->releaseLogicalSegmentNo(instancePtrs[i], iBuilder->CreateAdd(processedSegmentCount, iBuilder->getSize(1)));
    121         if (i == last_kernel) break;
    122         iBuilder->CreateBr(segmentWait[i+1]);
     138        if (kernels[i]->hasNoTerminateAttribute()) {
     139            kernels[i]->releaseLogicalSegmentNo(instancePtrs[i], iBuilder->CreateAdd(processedSegmentCount, iBuilder->getSize(1)));
     140            iBuilder->CreateBr(segmentWait[i+1]);
     141        }
     142        else {
     143            Value * terminated = kernels[i]->getTerminationSignal(instancePtrs[i]);
     144            kernels[i]->releaseLogicalSegmentNo(instancePtrs[i], iBuilder->CreateAdd(processedSegmentCount, iBuilder->getSize(1)));
     145            iBuilder->CreateCondBr(terminated, partialSegmentWait[i+1], segmentWait[i+1]);
     146        }
     147        if (partialSegmentWait[i] != nullptr) {
     148            iBuilder->SetInsertPoint(partialSegmentWait[i]);
     149            Value * processedSegmentCount = kernels[i]->acquireLogicalSegmentNo(instancePtrs[i]);
     150            Value * cond = iBuilder->CreateICmpEQ(segNo, processedSegmentCount);
     151            iBuilder->CreateCondBr(cond, partialSegmentLoopBody[i], partialSegmentWait[i]);
     152           
     153            iBuilder->SetInsertPoint(partialSegmentLoopBody[i]);
     154            kernels[i]->createDoSegmentCall(instancePtrs[i], segmentBlocks);
     155            kernels[i]->releaseLogicalSegmentNo(instancePtrs[i], iBuilder->CreateAdd(processedSegmentCount, iBuilder->getSize(1)));
     156            iBuilder->CreateBr(partialSegmentWait[i+1]);
     157        }
    123158    }
    124159   
    125     segNo->addIncoming(iBuilder->CreateAdd(segNo, ConstantInt::get(size_ty, threadNum)), segmentLoopBody[last_kernel]);
    126     Value * endSignal = kernels[last_kernel]->getTerminationSignal(instancePtrs[last_kernel]);
    127     iBuilder->CreateCondBr(endSignal, exitThreadBlock, segmentLoop);
    128    
    129160    iBuilder->SetInsertPoint(exitThreadBlock);
    130161    Value * nullVal = Constant::getNullValue(voidPtrTy);
     
    238269
    239270void generatePipelineLoop(IDISA::IDISA_Builder * iBuilder, std::vector<KernelBuilder *> kernels) {
    240    
    241    
    242271    for (auto k : kernels) k->createInstance();
    243272    //BufferMap bufferMap;
     
    301330    iBuilder->SetInsertPoint(exitBlock);
    302331}
    303 
    304 
    305 
    306 
    307 
    308 
    309 
    310 
    311 
    312 
    313 
    314 
    315 
    316 
    317 
    318 
    319 
    320 
    321 
    322 
Note: See TracChangeset for help on using the changeset viewer.