void build_sah(vector_t<PrimRef>& prims, isa::PrimInfo& pinfo) { size_t N = pinfo.size(); /* fast allocator that supports thread local operation */ FastAllocator allocator; for (size_t i=0; i<2; i++) { std::cout << "iteration " << i << ": building BVH over " << N << " primitives, " << std::flush; double t0 = getSeconds(); allocator.reset(); Node* root; isa::BVHBuilderBinnedSAH::build<Node*>( root, /* thread local allocator for fast allocations */ [&] () -> FastAllocator::ThreadLocal* { return allocator.threadLocal(); }, /* lambda function that creates BVH nodes */ [&](const isa::BVHBuilderBinnedSAH::BuildRecord& current, isa::BVHBuilderBinnedSAH::BuildRecord* children, const size_t N, FastAllocator::ThreadLocal* alloc) -> int { assert(N <= 2); InnerNode* node = new (alloc->malloc(sizeof(InnerNode))) InnerNode; for (size_t i=0; i<N; i++) { node->bounds[i] = children[i].pinfo.geomBounds; children[i].parent = (size_t*) &node->children[i]; } *current.parent = (size_t) node; return 0; }, /* lambda function that creates BVH leaves */ [&](const isa::BVHBuilderBinnedSAH::BuildRecord& current, FastAllocator::ThreadLocal* alloc) -> int { assert(current.prims.size() == 1); Node* node = new (alloc->malloc(sizeof(LeafNode))) LeafNode(prims[current.prims.begin()].ID(),prims[current.prims.begin()].bounds()); *current.parent = (size_t) node; return 0; }, /* progress monitor function */ [&] (size_t dn) { // throw an exception here to cancel the build operation }, prims.data(),pinfo,2,1024,1,1,1,1.0f,1.0f); double t1 = getSeconds(); std::cout << 1000.0f*(t1-t0) << "ms, " << 1E-6*double(N)/(t1-t0) << " Mprims/s, sah = " << root->sah() << " [DONE]" << std::endl; } }
bool run () { numFailed.store(0); size_t numThreads = getNumberOfLogicalThreads(); barrier.init(numThreads+1); /* create threads */ std::vector<thread_t> threads; for (size_t i=0; i<numThreads; i++) threads.push_back(createThread((thread_func)thread_alloc,this)); /* run test */ for (size_t i=0; i<1000; i++) { alloc.reset(); barrier.wait(); barrier.wait(); } /* destroy threads */ for (size_t i=0; i<numThreads; i++) join(threads[i]); return numFailed == 0; }
inline char* AllocateBlock( size_t s ) { # if !defined (NO_FAST_ALLOCATOR) char * const p = (char*)gFastAllocator.Allocate( s ); if ( p != 0 ) return p; # endif return (char*)EH_CSTD::malloc(s); }
void _STLP_CALL operator delete(void* s) # endif { if ( s != 0 ) { if ( !using_alloc_set ) { alloc_count--; if ( gTestController.TrackingEnabled() && gTestController.LeakDetectionEnabled() ) { using_alloc_set = true; allocation_set::iterator p = alloc_set().find( (char*)s ); EH_ASSERT( p != alloc_set().end() ); alloc_set().erase( p ); using_alloc_set = false; } } # if ! defined (NO_FAST_ALLOCATOR) if ( !gFastAllocator.Free( s ) ) # endif EH_CSTD::free(s); } }
inline void* MonomLex::operator new(std::size_t) { return Allocator.Allocate(); }
inline void MonomLex::operator delete(void* ptr) { Allocator.Free(ptr); }
void build_morton(vector_t<PrimRef>& prims, isa::PrimInfo& pinfo) { size_t N = pinfo.size(); /* array for morton builder */ vector_t<isa::MortonID32Bit> morton_src(N); vector_t<isa::MortonID32Bit> morton_tmp(N); for (size_t i=0; i<N; i++) morton_src[i].index = i; /* fast allocator that supports thread local operation */ FastAllocator allocator; for (size_t i=0; i<2; i++) { std::cout << "iteration " << i << ": building BVH over " << N << " primitives, " << std::flush; double t0 = getSeconds(); allocator.reset(); std::pair<Node*,BBox3fa> node_bounds = isa::bvh_builder_morton<Node*>( /* thread local allocator for fast allocations */ [&] () -> FastAllocator::ThreadLocal* { return allocator.threadLocal(); }, BBox3fa(empty), /* lambda function that allocates BVH nodes */ [&] ( isa::MortonBuildRecord<Node*>& current, isa::MortonBuildRecord<Node*>* children, size_t N, FastAllocator::ThreadLocal* alloc ) -> InnerNode* { assert(N <= 2); InnerNode* node = new (alloc->malloc(sizeof(InnerNode))) InnerNode; *current.parent = node; for (size_t i=0; i<N; i++) children[i].parent = &node->children[i]; return node; }, /* lambda function that sets bounds */ [&] (InnerNode* node, const BBox3fa* bounds, size_t N) -> BBox3fa { BBox3fa res = empty; for (size_t i=0; i<N; i++) { const BBox3fa b = bounds[i]; res.extend(b); node->bounds[i] = b; } return res; }, /* lambda function that creates BVH leaves */ [&]( isa::MortonBuildRecord<Node*>& current, FastAllocator::ThreadLocal* alloc, BBox3fa& box_o) -> Node* { assert(current.size() == 1); const size_t id = morton_src[current.begin].index; const BBox3fa bounds = prims[id].bounds(); // FIXME: dont use morton_src, should be input Node* node = new (alloc->malloc(sizeof(LeafNode))) LeafNode(id,bounds); *current.parent = node; box_o = bounds; return node; }, /* lambda that calculates the bounds for some primitive */ [&] (const isa::MortonID32Bit& morton) -> BBox3fa { return prims[morton.index].bounds(); }, /* progress monitor function */ [&] (size_t dn) { // throw an exception here to cancel the build operation }, morton_src.data(),morton_tmp.data(),prims.size(),2,1024,1,1); Node* root = node_bounds.first; double t1 = getSeconds(); std::cout << 1000.0f*(t1-t0) << "ms, " << 1E-6*double(N)/(t1-t0) << " Mprims/s, sah = " << root->sah() << " [DONE]" << std::endl; } }