Exemple #1
0
TriangleTree * ABTreeBuilder::buildTriangleTree(Rendering::Mesh * mesh) {
#ifdef MINSG_PROFILING
	std::cout << "Profiling: Creating ABTree(triangles=" << trianglesPerNode
				<< ", enlargement=" << allowedBBEnlargement << ")" << std::endl;
	Util::Utils::outputProcessMemory();
	Util::Timer timer;
	timer.reset();
#endif

	auto k = new ABTree(mesh, trianglesPerNode, allowedBBEnlargement);

#ifdef MINSG_PROFILING
	timer.stop();
	std::cout << "Profiling: Construction of root node: " << timer.getMilliseconds() << " ms" << std::endl;
	Util::Utils::outputProcessMemory();
	timer.reset();
#endif

	if (k->shouldSplit()) {
		k->split();
	}

#ifdef MINSG_PROFILING
	timer.stop();
	std::cout << "Profiling: Construction of tree structure: " << timer.getMilliseconds() << " ms" << std::endl;
	Util::Utils::outputProcessMemory();
#endif

	return k;
}
int test_statistics() {
	std::ofstream output("test_statistics.tsv");
	output << "class\tnumEventTypes\tnumEventsOverall\tduration\n";
	Util::Timer timer;
	for(uint32_t numRuns = 1; numRuns < 5; ++numRuns) {
		for(uint32_t numEventsOverall = 1; numEventsOverall <= 1000000; numEventsOverall *= 10) {
			for(uint32_t numEventTypes = 1; numEventTypes <= 32; numEventTypes *= 2) {
				timer.reset();
				testStatistics(numEventTypes, numEventsOverall);
				timer.stop();
				output << "Statistics\t" << numEventTypes << '\t' << numEventsOverall << '\t' << timer.getNanoseconds() << '\n';
				timer.reset();
				testProfiler(numEventTypes, numEventsOverall);
				timer.stop();
				output << "Profiler\t" << numEventTypes << '\t' << numEventsOverall << '\t' << timer.getNanoseconds() << '\n';
			}
		}
	}
	return EXIT_SUCCESS;
}
void Engine::setFPS(float dt) {
    static Util::Timer delay;
    static float sumDelta = 0.f;
    sumDelta += dt;
    if(!delay.running()) delay.start();
    static std::ostringstream str;
    if(delay.isElapsed(200)) {
        str.str("");
        str << "Trace Engine - " << (int)(1.f/dt) << " FPS";
        renderSystem_->setWindowTitle(str.str().c_str());
        str.str("");
        str << (int)(1.f/dt);
        delay.stop();
    }

//	fontRenderer_->renderText(str.str(), glm::vec3(10.f, 20.f, 50.f), "consola.ttf", glm::vec4(1.f, 1.f, 1.f, 1.f), 20);
//	fontRenderer_->renderText(Util::Str::formatTime(static_cast<int>(sumDelta)), glm::vec3(renderSystem_->resolution().x-100, 20.f, 50.f), "consola.ttf", glm::vec4(1.f, 1.f, 1.f, 1.f), 20);
}
	/*!
	 * \brief Constructor
	 * \param procedure Procedure to analyze
	 */
	LiveVariables::LiveVariables(const IR::Procedure &procedure, const FlowGraph &flowGraph)
		: mProcedure(procedure)
	{
		Util::Timer timer;
		timer.start();

		// Construct the set of all variables in the procedure
		std::set<const IR::Symbol*> all;
		for(const std::unique_ptr<IR::Symbol> &symbol : mProcedure.symbols()) {
			all.insert(symbol.get());
		}

		// Construct gen/kill sets for data flow analysis.
		std::map<const IR::Entry*, std::set<const IR::Symbol*>> gen;
		std::map<const IR::Entry*, std::set<const IR::Symbol*>> kill;
		for(const IR::Entry *entry : mProcedure.entries()) {
			for(const IR::Symbol *symbol : all) {
				std::set<const IR::Symbol*> &g = gen[entry];
				if(entry->uses(symbol)) {
					// An entry which uses a symbol adds that symbol to the set of live symbols
					g.insert(symbol);
				}

				const IR::Symbol *assign = entry->assign();
				if(assign && g.find(assign) == g.end()) {
					// An entry which assigns to a symbol and does not use it kills that symbol
					// from the live symbol set
					kill[entry].insert(assign);
				}
			}
		}

		// Perform a backwards data flow analysis on the procedure, using the gen and kill sets
		// constructed above.
		DataFlow<const IR::Symbol*> dataFlow;
		mMap = dataFlow.analyze(flowGraph, gen, kill, all, DataFlow<const IR::Symbol*>::Meet::Union, DataFlow<const IR::Symbol*>::Direction::Backward);

		Util::log("opt.time") << "  LiveVariables(" << mProcedure.name() << "): " << timer.stop() << "ms" << std::endl;
	}
//! ---|> Evaluator
void OccOverheadEvaluator::measure(FrameContext & context,Node & node,const Geometry::Rect & /*r*/) {

	//float currentRenderingTime=0;
	//int numTests=0;
	//int numVBO=0;
	int numPoly=0;
	Util::Color4f clearColor(0.5f, 0.5f, 0.9f, 1.0f);
	{ // 1. normal render pass
//        rc.clearScreen(0.5,0.5,0.9);
//        context.getRenderingContext().finish();
//        node.display(rc,renderingFlags);
		context.getRenderingContext().clearScreen(clearColor);
		node.display(context,renderingFlags|USE_WORLD_MATRIX);

		context.getRenderingContext().clearScreen(clearColor);
		context.getRenderingContext().finish();
		context.getStatistics().beginFrame();
		node.display(context,renderingFlags|USE_WORLD_MATRIX);
		context.getRenderingContext().finish();
		context.getStatistics().endFrame();
		numPoly=static_cast<int>(context.getStatistics().getValueAsDouble(context.getStatistics().getTrianglesCounter()));
	}

	// 2. test all group nodes if their bb is visible and collect them
	std::deque<GroupNode *> visibleGroupNodes;

	{
		// collect geometry nodes in frustum
		const auto groupNodesInVFList = collectNodesInFrustum<GroupNode>(&node,context.getCamera()->getFrustum());

		// setup occlusion queries
		int numQueries=groupNodesInVFList.size();
		if (numQueries==0) {
			values->push_back(nullptr); // TODO!!!
			return; // TODO??
		}

		auto queries = new Rendering::OcclusionQuery[numQueries];

		//  test bounding boxes
		context.getRenderingContext().pushAndSetDepthBuffer(Rendering::DepthBufferParameters(true, true, Rendering::Comparison::LEQUAL));
		int i=0;
		// start queries
		Rendering::OcclusionQuery::enableTestMode(context.getRenderingContext());
		for(const auto & groupNode : groupNodesInVFList) {
			queries[i].begin();
//            queries[i].fastBoxTest((*it)->getWorldBB());
			Rendering::drawAbsBox(context.getRenderingContext(), groupNode->getWorldBB() );
			queries[i].end();
			++i;
		}
		Rendering::OcclusionQuery::disableTestMode(context.getRenderingContext());
		i=0;
		// get results
		for(const auto & groupNode : groupNodesInVFList) {
			Geometry::Box extendedBox=groupNode->getWorldBB();
			extendedBox.resizeAbs(context.getCamera()->getNearPlane());

			if (queries[i].getResult() > 0 || extendedBox.contains(context.getCamera()->getWorldOrigin()) ) {
				visibleGroupNodes.push_back(groupNode);
			}
			++i;
		}
		context.getRenderingContext().popDepthBuffer();

		delete [] queries;
	}
	std::deque<GeometryNode *> geoNodesInVisibleGroupNodes;

	// 3. collect all direct geometry-node children
	{
		struct GeoChildrenCollector:public NodeVisitor {
			GeoChildrenCollector(std::deque<GeometryNode*> & _geoNodes,FrameContext & _context):
				geoNodes(_geoNodes),firstNode(true),frameContext(_context) {}
			virtual ~GeoChildrenCollector() {}

			std::deque<GeometryNode*> & geoNodes;
			bool firstNode;
			FrameContext & frameContext;

			// ---|> NodeVisitor
			NodeVisitor::status enter(Node * _node) override {
				// if this is the first call, continue...
				if(firstNode) {
					firstNode=false;
					return CONTINUE_TRAVERSAL;
				}
				// else collect the geometry children and break the traversal.
				GeometryNode * gn=dynamic_cast<GeometryNode *>(_node);
				if(gn){
					if(frameContext.getCamera()->testBoxFrustumIntersection( _node->getWorldBB()) != Geometry::Frustum::intersection_t::OUTSIDE)
						geoNodes.push_back(gn);
				}
				return BREAK_TRAVERSAL;
			}
		};
		for (auto & visibleGroupNode : visibleGroupNodes) {
			GeoChildrenCollector vis(geoNodesInVisibleGroupNodes,context);
			(visibleGroupNode)->traverse(vis);
		}

	}

	// 4. clear screen and measure time drawing children
	float perfectRenderingTime=0;
	{
		context.getRenderingContext().clearScreen(clearColor);

		context.getRenderingContext().finish();
		Util::Timer timer;
		timer.reset();

		for (auto & geoNodesInVisibleGroupNode : geoNodesInVisibleGroupNodes) {
			context.displayNode((geoNodesInVisibleGroupNode),renderingFlags|USE_WORLD_MATRIX);
		}

		context.getRenderingContext().finish();
		timer.stop();
		perfectRenderingTime=timer.getMilliseconds();
	}

//    // Test-costs:
//    float result=numTests!=0?(currentRenderingTime-perfectRenderingTime)/numTests:0;

	// currentRenderingTime-perfRendering:
//    float result=currentRenderingTime-perfectRenderingTime;

	float result=numPoly>0?perfectRenderingTime*1000/numPoly:0;

//    std::cout <<currentRenderingTime<<"-"<<perfectRenderingTime<<"="<<result<<"\t"<<numTests<<"\n";
//    std::cout <<numVBO<<":"<<geoNodesInVisibleGroupNodes.size()<<"\n";

//   float result=perfectRenderingTime;
//    values.push_back(currentRenderingTime);
//    values.push_back(perfectRenderingTime);
	values->push_back(new Util::_NumberAttribute<float>(result));

//    if(mode==SINGLE_VALUE){
//        if(result>renderingTime || renderingTime==0)
//            renderingTime=result;
//    }else{
//        values.push_back(result);
//    }

//    renderingTime=0;
}
int test_spherical_sampling_serialization() {
#ifdef MINSG_EXT_SVS
	std::cout << "Test serialization of SVS objects ... ";
	Util::Timer timer;
	timer.reset();

	using namespace MinSG::SVS;
	MinSG::SceneManagement::SceneManager sceneManager;

	const uint32_t count = 10;
	std::array<Util::Reference<MinSG::GeometryNode>, count> nodes;
	for(uint_fast32_t i = 0; i < count; ++i) {
		nodes[i] = new MinSG::GeometryNode;
		sceneManager.registerNode(std::string("Node") + Util::StringUtils::toString(i), nodes[i].get());
	}
	MinSG::VisibilitySubdivision::VisibilityVector vv;
	for(uint_fast32_t i = 0; i < count; ++i) {
		vv.setNode(nodes[i].get(), i);
	}

	std::vector<SamplePoint> samples;
	{
		using namespace Rendering::MeshUtils::PlatonicSolids;
		Util::Reference<Rendering::Mesh> mesh = createEdgeSubdivisionSphere(createIcosahedron(), 4);
		auto accessor = Rendering::PositionAttributeAccessor::create(mesh->openVertexData(), Rendering::VertexAttributeIds::POSITION);
		for(std::size_t i = 0; accessor->checkRange(i); ++i) {
			samples.emplace_back(accessor->getPosition(i));
		}
	}
	{
		std::stringstream stream;
		stream.precision(std::numeric_limits<long double>::digits10);
		// Serialize
		for(const auto & sample : samples) {
			stream << sample.getPosition() << ' ';
			sample.getValue().serialize(stream, sceneManager);
			stream << ' ';
		}
		// Unserialize
		std::vector<SamplePoint> newSamples;
		for(std::size_t s = 0; s < samples.size(); ++s) {
			Geometry::Vec3f pos;
			stream >> pos;
			SamplePoint sample(pos);
			sample.setValue(MinSG::VisibilitySubdivision::VisibilityVector::unserialize(stream, sceneManager));
			newSamples.push_back(sample);
		}
		for(std::size_t s = 0; s < samples.size(); ++s) {
			const SamplePoint & oldSample = samples[s];
			const SamplePoint & newSample = newSamples[s];
			if(oldSample.getPosition().distance(newSample.getPosition()) > std::numeric_limits<float>::epsilon()) {
				std::cout << "Serialization/unserialization failed." << std::endl;
				return EXIT_FAILURE;
			}
			const auto & oldVV = oldSample.getValue();
			const auto & newVV = newSample.getValue();
			for(uint_fast32_t n = 0; n < count; ++n) {
				if(oldVV.getBenefits(nodes[n].get()) != newVV.getBenefits(nodes[n].get())) {
					std::cout << "Serialization/unserialization failed." << std::endl;
					return EXIT_FAILURE;
				}
			}
		}
	}
	VisibilitySphere visibilitySphere(Geometry::Sphere_f(Geometry::Vec3f(1.0f, 2.0f, 3.0f), 17.0f), samples);
	{
		std::stringstream stream;
		stream.precision(std::numeric_limits<long double>::digits10);
		// Serialize
		stream << visibilitySphere.getSphere() << ' ' << samples.size();
		for(const auto & sample : samples) {
			stream << ' ' << sample.getPosition() << ' ';
			sample.getValue().serialize(stream, sceneManager);
			stream << ' ';
		}
		
		// Unserialize
		Geometry::Sphere_f sphere;
		stream >> sphere;
		std::size_t sampleCount;
		stream >> sampleCount;
		std::vector<SamplePoint> newSamples;
		for(std::size_t s = 0; s < sampleCount; ++s) {
			Geometry::Vec3f pos;
			stream >> pos;
			SamplePoint sample(pos);
			sample.setValue(MinSG::VisibilitySubdivision::VisibilityVector::unserialize(stream, sceneManager));
			newSamples.push_back(sample);
		}
		
		VisibilitySphere newVisibilitySphere(sphere, newSamples);
		if(!(visibilitySphere.getSphere() == newVisibilitySphere.getSphere())) {
			std::cout << "Serialization/unserialization failed." << std::endl;
			return EXIT_FAILURE;
		}
		for(std::size_t s = 0; s < samples.size(); ++s) {
			const SamplePoint & oldSample = visibilitySphere.getSamples()[s];
			const SamplePoint & newSample = newVisibilitySphere.getSamples()[s];
			if(oldSample.getPosition().distance(newSample.getPosition()) > std::numeric_limits<float>::epsilon()) {
				std::cout << "Serialization/unserialization failed." << std::endl;
				return EXIT_FAILURE;
			}
			const auto & oldVV = oldSample.getValue();
			const auto & newVV = newSample.getValue();
			for(uint_fast32_t n = 0; n < count; ++n) {
				if(oldVV.getBenefits(nodes[n].get()) != newVV.getBenefits(nodes[n].get())) {
					std::cout << "Serialization/unserialization failed." << std::endl;
					return EXIT_FAILURE;
				}
			}
		}
	}

	timer.stop();
	std::cout << "done (duration: " << timer.getSeconds() << " s).\n";
#endif /* MINSG_EXT_SVS */
	return EXIT_SUCCESS;
}
int test_spherical_sampling() {
#ifdef MINSG_EXT_SVS
	std::cout << "Test SVS ... ";
	Util::Timer timer;
	timer.reset();

	MinSG::SceneManagement::SceneManager sceneManager;
	MinSG::FrameContext frameContext;

	Rendering::VertexDescription vertexDesc;
	vertexDesc.appendPosition3D();
	Util::Reference<Rendering::Mesh> boxMesh = Rendering::MeshUtils::MeshBuilder::createBox(vertexDesc, Geometry::Box(Geometry::Vec3f(0.5f, 0.5f, 0.5f), 1));

	/*
	 * Create a 1D array of n unit-size boxes in the x axis
	 *
	 *          /
	 *        ..L2
	 *        /  /
	 *    ......L1  /
	 *    /    /  /
	 *  ...L0....  /  /
	 *  /  /  /  /  /
	 * ------------------------- ... -----
	 * | 0 | 1 | 2 | 3 | 4 | 5 |   | n |
	 * |  |  |  |  |  |  |   |  |
	 * ------------------------- ... -----
	 * ^        ^       ^
	 * |        |       |
	 * x=0       x=4      x=n
	 *
	 * The first three boxes are put into the first list node L0.
	 * L0 together with the fourth box are put into the second list node L1.
	 */
	const uint32_t count = 512;

	std::vector<Util::Reference<MinSG::ListNode>> listNodes;
	std::vector<Util::Reference<MinSG::GeometryNode>> boxNodes;
	for(uint_fast32_t x = 0; x < count; ++x) {
		MinSG::GeometryNode * geoNode = new MinSG::GeometryNode(boxMesh);
		geoNode->moveLocal(Geometry::Vec3f(x, 0, 0));
		sceneManager.registerNode(std::string("Node") + Util::StringUtils::toString(x), geoNode);
		boxNodes.push_back(geoNode);
		if(x != 1 && x != 2) {
			listNodes.push_back(new MinSG::ListNode);
		}
		if(x < 3) {
			listNodes.front()->addChild(geoNode);
		} else {
			listNodes[x - 2]->addChild(listNodes[x - 3].get());
			listNodes[x - 2]->addChild(geoNode);
		}
	}

	// Debug output of created scene graph
	//MinSG::GraphVizOutput::treeToFile(listNodes.back().get(), &sceneManager, Util::FileName("output.dot"));

	// Perform the sampling
	std::vector<Geometry::Vec3f> positions;
	positions.emplace_back(-1, 0, 0); // left
	positions.emplace_back(1, 0, 0); // right
	positions.emplace_back(0, 1, 0); // top
	positions.emplace_back(0, 0, 1); // back

	// The resolution has to be at least the number of boxes. Otherwise, boxes will be missed during visibility testing.
	MinSG::SVS::PreprocessingContext preprocessingContext(sceneManager, frameContext, listNodes.back().get(), positions, count, false, false);
	while(!preprocessingContext.isFinished()) {
		preprocessingContext.preprocessSingleNode();
	}

	// Validate the results
	for(uint_fast32_t listIndex = 0; listIndex < count - 2; ++listIndex) {
		MinSG::ListNode * listNode = listNodes[listIndex].get();
		const MinSG::SVS::VisibilitySphere & visibilitySphere = MinSG::SVS::retrieveVisibilitySphere(listNode);
		{
			// Because the geometry is built of axis-aligned bounding boxes only, the sphere has to contain the group's bounding box.
			assert(visibilitySphere.getSphere().distance(listNode->getBB().getMin()) < 1.0e-9);
			assert(visibilitySphere.getSphere().distance(listNode->getBB().getMax()) < 1.0e-9);
		}
		{
			// left => only first box must be visible
			const auto vv = visibilitySphere.queryValue(positions[0], MinSG::SVS::INTERPOLATION_NEAREST);
			assert(vv.getBenefits(boxNodes.front().get()) > 0);
			for(uint_fast32_t boxIndex = 1; boxIndex < count; ++boxIndex) {
				MinSG::GeometryNode * geoNode = boxNodes[boxIndex].get();
				assert(vv.getBenefits(geoNode) == 0);
			}
		}
		{
			// right => only last box inside the subtree must be visible
			const auto vv = visibilitySphere.queryValue(positions[1], MinSG::SVS::INTERPOLATION_NEAREST);
			const uint32_t lastBoxIndex = listIndex + 2;
			assert(vv.getBenefits(boxNodes[lastBoxIndex].get()) > 0);
			for(uint_fast32_t boxIndex = 0; boxIndex < count; ++boxIndex) {
				if(boxIndex != lastBoxIndex) {
					MinSG::GeometryNode * geoNode = boxNodes[boxIndex].get();
					assert(vv.getBenefits(geoNode) == 0);
				}
			}
		}
		// top, back => all boxes in the subtree must be visible
		for(uint_fast32_t posIndex = 2; posIndex <= 3; ++posIndex) {
			const auto vv = visibilitySphere.queryValue(positions[posIndex], MinSG::SVS::INTERPOLATION_NEAREST);
			const auto geoNodes = MinSG::collectNodes<MinSG::GeometryNode>(listNode);
			for(const auto & geoNode : geoNodes) {
				assert(vv.getBenefits(geoNode) > 0);
			}
		}
	}

	boxNodes.clear();
	MinSG::destroy(listNodes.back().get());
	listNodes.clear();

	timer.stop();
	std::cout << "done (duration: " << timer.getSeconds() << " s).\n";
#endif /* MINSG_EXT_SVS */
	return EXIT_SUCCESS;
}
Exemple #8
0
int test_OutOfCore() {
#ifdef MINSG_EXT_OUTOFCORE
	const bool verbose = true;

	// Tests for MinSG::OutOfCore::CacheObjectPriority
	if(sizeof(MinSG::OutOfCore::CacheObjectPriority) != 8) {
		return EXIT_FAILURE;
	}
	if(!(MinSG::OutOfCore::CacheObjectPriority(1, 2, 3) == MinSG::OutOfCore::CacheObjectPriority(1, 2, 3))) {
		return EXIT_FAILURE;
	}
	if(!(MinSG::OutOfCore::CacheObjectPriority(1, 100, 100) < MinSG::OutOfCore::CacheObjectPriority(2, 0, 0))) {
		return EXIT_FAILURE;
	}
	if(!(MinSG::OutOfCore::CacheObjectPriority(2, 1, 100) < MinSG::OutOfCore::CacheObjectPriority(2, 2, 0))) {
		return EXIT_FAILURE;
	}
	if(!(MinSG::OutOfCore::CacheObjectPriority(2, 2, 1) < MinSG::OutOfCore::CacheObjectPriority(2, 2, 2))) {
		return EXIT_FAILURE;
	}

	std::default_random_engine engine;
	std::uniform_int_distribution<std::size_t> vertexCountDist(10, 1000);
	const uint32_t numMeshes = 30000;
	const Util::TemporaryDirectory tempDir("MinSGTest_OutOfCore");
	
	// Create empty meshes and save them into a subdirectory.
	{
		Rendering::VertexDescription vertexDesc;
		vertexDesc.appendPosition3D();
		
		for(uint_fast32_t i = 0; i < numMeshes; ++i) {
			Util::Reference<Rendering::Mesh> mesh = new Rendering::Mesh(vertexDesc, vertexCountDist(engine), 64);
			Rendering::MeshVertexData & vertexData = mesh->openVertexData();
			std::fill_n(vertexData.data(), vertexData.dataSize(), 0);
			vertexData.markAsChanged();
			Rendering::MeshIndexData & indexData = mesh->openIndexData();
			std::fill_n(indexData.data(), indexData.getIndexCount(), 0);
			indexData.markAsChanged();
			const std::string numberString = Util::StringUtils::toString<uint32_t>(i);
			Rendering::Serialization::saveMesh(mesh.get(), Util::FileName(tempDir.getPath().getDir() + numberString + ".mmf"));
		}
	}
	
	// Set up the OutOfCore system.
	MinSG::FrameContext frameContext;
	
	MinSG::OutOfCore::setUp(frameContext);

	MinSG::OutOfCore::CacheManager & manager = MinSG::OutOfCore::getCacheManager();
	manager.addCacheLevel(MinSG::OutOfCore::CacheLevelType::FILE_SYSTEM, 0);
	manager.addCacheLevel(MinSG::OutOfCore::CacheLevelType::FILES, 512 * kibibyte);
	manager.addCacheLevel(MinSG::OutOfCore::CacheLevelType::MAIN_MEMORY, 256 * kibibyte);
	
	Util::Timer addTimer;
	addTimer.reset();
	std::cout << "Adding meshes ..." << std::flush;
	
	// Add the meshes to the OutOfCore system.
	std::vector<Util::Reference<Rendering::Mesh> > meshes;
	meshes.reserve(numMeshes);
	static const Geometry::Box boundingBox(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
	for(uint_fast32_t i = 0; i < numMeshes; ++i) {
		const std::string numberString = Util::StringUtils::toString<uint32_t>(i);
		meshes.push_back(MinSG::OutOfCore::addMesh(Util::FileName(tempDir.getPath().getDir() + numberString + ".mmf"), boundingBox));
	}
	
	manager.trigger();
	
	addTimer.stop();
	std::cout << " done (" << addTimer.getSeconds() << " s)" << std::endl;
	
	Util::Timer displayTimer;
	Util::Timer assureLocalTimer;
	Util::Timer overallTimer;
	overallTimer.reset();

	uint32_t frame = 0;

	{
		// Simulate frames to get the OutOfCore system working.
		std::uniform_int_distribution<std::size_t> indexDist(0, meshes.size() - 1);
		for(; frame < 10; ++frame) {
			std::cout << "Executing frame " << frame << " ..." << std::flush;
			frameContext.beginFrame();
			displayTimer.reset();
			// Simulate display of meshes to change the priorities of the system.
			for(uint32_t i = 0; i < meshes.size() / 2; ++i) {
				const uint32_t meshIndex = indexDist(engine);
				Rendering::Mesh * mesh = meshes[meshIndex].get();
				manager.meshDisplay(mesh);
			}
			manager.trigger();
			displayTimer.stop();
			assureLocalTimer.reset();
			for(uint32_t i = 0; i < 10; ++i) {
				const uint32_t meshIndex = indexDist(engine);
				
				Rendering::Mesh * mesh = meshes[meshIndex].get();
				const Rendering::MeshVertexData & vd = mesh->openVertexData();
				const Rendering::MeshIndexData & id = mesh->openIndexData();
				
				if (!vd.hasLocalData() || !id.hasLocalData()) {
					std::cout << "Error: Mesh has no local data." << std::endl;
					return EXIT_FAILURE;
				}
			}
			assureLocalTimer.stop();
			frameContext.endFrame();
			std::cout << " done (display: " << displayTimer.getSeconds() << " s, assureLocal: " << assureLocalTimer.getSeconds() << " s)" << std::endl;

			if(verbose) {
				outputCacheLevelInformation();
			}
		}
	}

	for(uint32_t round = 0; round < 10; ++round) {
		Util::Timer addAgainTimer;
		addAgainTimer.reset();
		std::cout << "Adding additional meshes ..." << std::flush;
		
		// Simulate loading a second scene by adding meshes again.
		meshes.reserve(meshes.size() + 3 * numMeshes);
		for(uint_fast32_t i = 0; i < numMeshes; ++i) {
			const std::string numberString = Util::StringUtils::toString<uint32_t>(i);
			meshes.push_back(MinSG::OutOfCore::addMesh(Util::FileName(tempDir.getPath().getDir() + numberString + ".mmf"), boundingBox));
			meshes.push_back(MinSG::OutOfCore::addMesh(Util::FileName(tempDir.getPath().getDir() + numberString + ".mmf"), boundingBox));
			meshes.push_back(MinSG::OutOfCore::addMesh(Util::FileName(tempDir.getPath().getDir() + numberString + ".mmf"), boundingBox));
		}
		
		manager.trigger();
		
		addAgainTimer.stop();
		std::cout << " done (" << addAgainTimer.getSeconds() << " s)" << std::endl;

		// Simulate frames to get the OutOfCore system working.
		std::normal_distribution<double> indexDist(meshes.size() / 2, std::sqrt(meshes.size() / 2));
		const auto untilFrame = frame + 5;
		for(; frame < untilFrame; ++frame) {
			std::cout << "Executing frame " << frame << " ..." << std::flush;
			frameContext.beginFrame();
			displayTimer.reset();
			// Simulate display of meshes to change the priorities of the system.
			for(uint32_t i = 0; i < meshes.size() / 10; ++i) {
				const std::size_t meshIndex = std::max(static_cast<std::size_t>(0), std::min(static_cast<std::size_t>(indexDist(engine)), meshes.size() - 1));
				Rendering::Mesh * mesh = meshes[meshIndex].get();
				manager.meshDisplay(mesh);
			}
			manager.trigger();
			displayTimer.stop();
			frameContext.endFrame();
			std::cout << " done (display: " << displayTimer.getSeconds() << " s)" << std::endl;

			if(verbose) {
				outputCacheLevelInformation();
			}
		}
	}

	overallTimer.stop();
	std::cout << "Overall duration: " << overallTimer.getSeconds() << " s" << std::endl;
	
	MinSG::OutOfCore::shutDown();
	
	return EXIT_SUCCESS;
#else /* MINSG_EXT_OUTOFCORE */
	return EXIT_FAILURE;
#endif /* MINSG_EXT_OUTOFCORE */
}
Exemple #9
0
	/*!
	 * \brief Optimize a program
	 * \param program Program to optimize
	 */
	void Optimizer::optimize(IR::Program &program)
	{
		std::vector<Transform::Transform*> startingTransforms;
		std::map<Transform::Transform*, std::vector<Transform::Transform*>> transformMap;

		// Build the list of all transforms
		startingTransforms.push_back(Transform::CopyProp::instance());
		startingTransforms.push_back(Transform::ConstantProp::instance());
		startingTransforms.push_back(Transform::DeadCodeElimination::instance());
		startingTransforms.push_back(Transform::ThreadJumps::instance());
		startingTransforms.push_back(Transform::LoopInvariantCodeMotion::instance());
		startingTransforms.push_back(Transform::CommonSubexpressionElimination::instance());

		// Transforms to run after CopyProp
		transformMap[Transform::CopyProp::instance()].push_back(Transform::DeadCodeElimination::instance());

		// Transforms to run after Constant Prop
		transformMap[Transform::ConstantProp::instance()].push_back(Transform::DeadCodeElimination::instance());

		// Transforms to run after DeadCodeElimination
		transformMap[Transform::DeadCodeElimination::instance()].push_back(Transform::ConstantProp::instance());
		transformMap[Transform::DeadCodeElimination::instance()].push_back(Transform::CopyProp::instance());

		// Transforms to run after CommonSubexpressionElimination
		transformMap[Transform::CommonSubexpressionElimination::instance()].push_back(Transform::CopyProp::instance());

		// Optimize each procedure in turn
		for(std::unique_ptr<IR::Procedure> &procedure : program.procedures()) {
			Analysis::Analysis analysis(*procedure);

			// Queue of transformations to run
			Util::UniqueQueue<Transform::Transform*> transforms;

			// Start by running each optimization pass once
			for(Transform::Transform *transform : startingTransforms) {
				transforms.push(transform);
			}

			Util::log("opt") << "Optimizations (" << procedure->name() << "):" << std::endl;

			// Run optimization passes until there are none left
			while(!transforms.empty()) {
				Transform::Transform *transform = transforms.front();
				transforms.pop();

				// Run the transform
				Util::Timer timer;
				timer.start();
				bool changed = transform->transform(*procedure, analysis);
				Util::log("opt.time") << transform->name() << ": " << timer.stop() << "ms" << std::endl;

				if(changed) {
					procedure->print(Util::log("opt.ir"));
					Util::log("opt.ir") << std::endl;

					// If the transform changed the IR, add its follow-up transformations to the queue
					std::vector<Transform::Transform*> &newTransforms = transformMap[transform];
					for(Transform::Transform *newTransform : newTransforms) {
						transforms.push(newTransform);
					}
				}
			}

			Util::log("opt") << std::endl;
		}
	}