Skip to content
Snippets Groups Projects
SimpleLawsTest.cpp 2.78 KiB
Newer Older
  • Learn to ignore specific revisions
  • #include "emper.hpp"
    
    #include "LawsStrategy.hpp"
    #include "Fiber.hpp"
    
    #include <random>
    
    static const unsigned int ROUND_COUNT = 10;
    static const unsigned int FIBER_LOOPS = 10;
    
    static const unsigned int PAYLOAD_COUNT = 4096;
    typedef struct ALIGN_TO_CACHE_LINE {
    	// 4096 * 8 byte (64 bit) = 32 KiB = L1 cache size of most systems
    	uint64_t payload[PAYLOAD_COUNT];
    	CPS* cps;
    	unsigned int fiberNum;
    } FiberData;
    
    typedef struct ALIGN_TO_CACHE_LINE {
    	workeraffinity_t affinity;
    } AlignedWorkerAffinity;
    
    
    static void fiberFun(void* voidFiberData) {
    	FiberData* fiberData = static_cast<FiberData*>(voidFiberData);
    
    	std::random_device randomDevice;
    	std::mt19937_64 randomGenerator(randomDevice());
    	std::uniform_int_distribution<unsigned long long> randomDistribution(0, UINT64_MAX);
    
    	for (unsigned int i = 0; i < FIBER_LOOPS; ++i) {
    		for (unsigned int j = 0; j < PAYLOAD_COUNT; ++j) {
    			unsigned long long r = randomDistribution(randomGenerator);
    			fiberData->payload[j] += r;
    		}
    	}
    
    	fiberData->cps->signalAndExit();
    }
    
    static void alphaFun() {
    	Runtime* runtime = Runtime::getRuntime();
    	const unsigned int FIBER_COUNT = runtime->getWorkerCount() + 3;
    
    	AlignedWorkerAffinity *affinities = new AlignedWorkerAffinity[FIBER_COUNT];
    	FiberData* fiberData = new FiberData[FIBER_COUNT];
    
    	for (unsigned int i = 0; i < FIBER_COUNT; ++i) {
    		FiberData& currentFiberData = fiberData[i];
    		memset(currentFiberData.payload, 0, sizeof(uint64_t) * PAYLOAD_COUNT);
    		currentFiberData.fiberNum = i;
    		currentFiberData.cps = nullptr;
    
    
    		affinities[i].affinity = Fiber::NOT_AFFINE;
    
    	}
    
    	for (unsigned int round = 0; round < ROUND_COUNT; ++round) {
    		CPS cps(FIBER_COUNT);
    		for (unsigned int i = 0; i < FIBER_COUNT; ++i) {
    			FiberData* myFiberData = &fiberData[i];
    			myFiberData->cps = &cps;
    			Fiber* fiber = Fiber::from(&fiberFun,
    									   myFiberData,
    									   &affinities[i].affinity);
    			runtime->schedule(*fiber);
    		}
    		cps.wait();
    	}
    
    	std::atomic<uint64_t> finalResult(0);
    	CPS cps(FIBER_COUNT);
    	for (unsigned int i = 0; i < FIBER_COUNT; ++i) {
    		FiberData* myFiberData = &fiberData[i];
    		myFiberData->cps = &cps;
    		Fiber* fiber = Fiber::from([myFiberData, &finalResult]() {
    				uint64_t mySum = 0;
    				for (unsigned int i = 0; i < PAYLOAD_COUNT; ++i) {
    					mySum += myFiberData->payload[i];
    				}
    				finalResult += mySum;
    
    				myFiberData->cps->signalAndExit();
    			},
    			&affinities[i].affinity);
    		runtime->schedule(*fiber);
    	}
    
    
    	free(fiberData);
    	free(affinities);
    
    	std::cerr << "Result: " << finalResult << std::endl;
    
    	exit(EXIT_SUCCESS);
    }
    
    int main(UNUSED_ARG int args, UNUSED_ARG char *argv[]) {
    	RuntimeStrategy& lawsStrategy = LawsStrategy::INSTANCE;
    	Runtime runtime(lawsStrategy);
    
    	Fiber* alphaFiber = Fiber::from(&alphaFun);
    
    	runtime.schedule(*alphaFiber);
    
    	runtime.waitUntilFinished();
    
    	return 0;
    }