// ======================================================================== // // Copyright 2009-2014 Intel Corporation // // // // Licensed under the Apache License, Version 2.0 (the "License"); // // you may not use this file except in compliance with the License. // // You may obtain a copy of the License at // // // // http://www.apache.org/licenses/LICENSE-2.0 // // // // Unless required by applicable law or agreed to in writing, software // // distributed under the License is distributed on an "AS IS" BASIS, // // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // // See the License for the specific language governing permissions and // // limitations under the License. // // ======================================================================== // #include "sys/platform.h" #include "sys/ref.h" #include "embree2/rtcore.h" #include "embree2/rtcore_ray.h" #include "math/vec3.h" #include "../kernels/common/default.h" #include namespace embree { RTCAlgorithmFlags aflags = (RTCAlgorithmFlags) (RTC_INTERSECT1 | RTC_INTERSECT4 | RTC_INTERSECT8 | RTC_INTERSECT16); /* configuration */ static std::string g_rtcore = ""; static size_t g_plot_min = 0; static size_t g_plot_max = 0; static size_t g_plot_step= 0; static std::string g_plot_test = ""; /* vertex and triangle layout */ struct Vertex { float x,y,z,a; }; struct Triangle { int v0, v1, v2; }; #define AssertNoError() \ if (rtcGetError() != RTC_NO_ERROR) return false; #define AssertAnyError() \ if (rtcGetError() == RTC_NO_ERROR) return false; #define AssertError(code) \ if (rtcGetError() != code) return false; std::vector g_threads; MutexSys g_mutex; BarrierSys g_barrier; LinearBarrierActive g_barrier_active; size_t g_num_mutex_locks = 100000; size_t g_num_threads = 0; atomic_t g_atomic_cntr = 0; class Benchmark { public: const std::string name; const std::string unit; Benchmark (const std::string& name, const std::string& unit) : name(name), unit(unit) {} virtual double run(size_t numThreads) = 0; void print(size_t numThreads, size_t N) { double pmin = inf, pmax = -float(inf), pavg = 0.0f; for (size_t j=0; j 0); if (threadIndex != 0) g_barrier_active.wait(threadIndex,threadCount); } double run (size_t numThreads) { g_atomic_cntr = N; g_num_threads = numThreads; g_barrier_active.init(numThreads); for (size_t i=1; i vertices; std::vector triangles; }; void createSphereMesh (const Vec3f pos, const float r, size_t numPhi, Mesh& mesh_o) { /* create a triangulated sphere */ size_t numTheta = 2*numPhi; mesh_o.vertices.resize(numTheta*(numPhi+1)); mesh_o.triangles.resize(2*numTheta*(numPhi-1)); /* map triangle and vertex buffer */ Vertex* vertices = (Vertex* ) &mesh_o.vertices[0]; Triangle* triangles = (Triangle*) &mesh_o.triangles[0]; /* create sphere geometry */ int tri = 0; const float rcpNumTheta = 1.0f/float(numTheta); const float rcpNumPhi = 1.0f/float(numPhi); for (size_t phi=0; phi<=numPhi; phi++) { for (size_t theta=0; theta 1) { triangles[tri].v0 = p10; triangles[tri].v1 = p00; triangles[tri].v2 = p01; tri++; } if (phi < numPhi) { triangles[tri].v0 = p11; triangles[tri].v1 = p10; triangles[tri].v2 = p01; tri++; } } } } unsigned addSphere (RTCScene scene, RTCGeometryFlags flag, const Vec3f pos, const float r, size_t numPhi) { Mesh mesh; createSphereMesh (pos, r, numPhi, mesh); unsigned geom = rtcNewTriangleMesh (scene, flag, mesh.triangles.size(), mesh.vertices.size()); memcpy(rtcMapBuffer(scene,geom,RTC_VERTEX_BUFFER), &mesh.vertices[0], mesh.vertices.size()*sizeof(Vertex)); memcpy(rtcMapBuffer(scene,geom,RTC_INDEX_BUFFER ), &mesh.triangles[0], mesh.triangles.size()*sizeof(Triangle)); rtcUnmapBuffer(scene,geom,RTC_VERTEX_BUFFER); rtcUnmapBuffer(scene,geom,RTC_INDEX_BUFFER); return geom; } class create_geometry : public Benchmark { public: RTCSceneFlags sflags; RTCGeometryFlags gflags; size_t numPhi; size_t numMeshes; create_geometry (const std::string& name, RTCSceneFlags sflags, RTCGeometryFlags gflags, size_t numPhi, size_t numMeshes) : Benchmark(name,"Mtris/s"), sflags(sflags), gflags(gflags), numPhi(numPhi), numMeshes(numMeshes) {} double run(size_t numThreads) { rtcInit((g_rtcore+",threads="+std::stringOf(numThreads)).c_str()); Mesh mesh; createSphereMesh (Vec3f(0,0,0), 1, numPhi, mesh); double t0 = getSeconds(); RTCScene scene = rtcNewScene(sflags,aflags); for (size_t i=0; i benchmarks; void create_benchmarks() { benchmarks.push_back(new benchmark_mutex_sys()); benchmarks.push_back(new benchmark_barrier_sys()); benchmarks.push_back(new benchmark_barrier_active()); benchmarks.push_back(new benchmark_atomic_inc()); benchmarks.push_back(new benchmark_osmalloc()); benchmarks.push_back(new benchmark_bandwidth()); benchmarks.push_back(new create_geometry ("create_static_geometry_120", RTC_SCENE_STATIC,RTC_GEOMETRY_STATIC,6,1)); benchmarks.push_back(new create_geometry ("create_static_geometry_1k" , RTC_SCENE_STATIC,RTC_GEOMETRY_STATIC,17,1)); benchmarks.push_back(new create_geometry ("create_static_geometry_10k", RTC_SCENE_STATIC,RTC_GEOMETRY_STATIC,51,1)); benchmarks.push_back(new create_geometry ("create_static_geometry_100k", RTC_SCENE_STATIC,RTC_GEOMETRY_STATIC,159,1)); benchmarks.push_back(new create_geometry ("create_static_geometry_1000k_1", RTC_SCENE_STATIC,RTC_GEOMETRY_STATIC,501,1)); benchmarks.push_back(new create_geometry ("create_static_geometry_100k_10", RTC_SCENE_STATIC,RTC_GEOMETRY_STATIC,159,10)); benchmarks.push_back(new create_geometry ("create_static_geometry_10k_100", RTC_SCENE_STATIC,RTC_GEOMETRY_STATIC,51,100)); benchmarks.push_back(new create_geometry ("create_static_geometry_1k_1000" , RTC_SCENE_STATIC,RTC_GEOMETRY_STATIC,17,1000)); #if defined(__X86_64__) benchmarks.push_back(new create_geometry ("create_static_geometry_120_10000",RTC_SCENE_STATIC,RTC_GEOMETRY_STATIC,6,8334)); #endif benchmarks.push_back(new create_geometry ("create_dynamic_geometry_120", RTC_SCENE_DYNAMIC,RTC_GEOMETRY_STATIC,6,1)); benchmarks.push_back(new create_geometry ("create_dynamic_geometry_1k" , RTC_SCENE_DYNAMIC,RTC_GEOMETRY_STATIC,17,1)); benchmarks.push_back(new create_geometry ("create_dynamic_geometry_10k", RTC_SCENE_DYNAMIC,RTC_GEOMETRY_STATIC,51,1)); benchmarks.push_back(new create_geometry ("create_dynamic_geometry_100k", RTC_SCENE_DYNAMIC,RTC_GEOMETRY_STATIC,159,1)); benchmarks.push_back(new create_geometry ("create_dynamic_geometry_1000k_1", RTC_SCENE_DYNAMIC,RTC_GEOMETRY_STATIC,501,1)); benchmarks.push_back(new create_geometry ("create_dynamic_geometry_100k_10", RTC_SCENE_DYNAMIC,RTC_GEOMETRY_STATIC,159,10)); benchmarks.push_back(new create_geometry ("create_dynamic_geometry_10k_100", RTC_SCENE_DYNAMIC,RTC_GEOMETRY_STATIC,51,100)); benchmarks.push_back(new create_geometry ("create_dynamic_geometry_1k_1000" , RTC_SCENE_DYNAMIC,RTC_GEOMETRY_STATIC,17,1000)); #if defined(__X86_64__) benchmarks.push_back(new create_geometry ("create_dynamic_geometry_120_10000",RTC_SCENE_DYNAMIC,RTC_GEOMETRY_STATIC,6,8334)); #endif benchmarks.push_back(new update_geometry ("refit_geometry_120", RTC_GEOMETRY_DEFORMABLE,6,1)); benchmarks.push_back(new update_geometry ("refit_geometry_1k" , RTC_GEOMETRY_DEFORMABLE,17,1)); benchmarks.push_back(new update_geometry ("refit_geometry_10k", RTC_GEOMETRY_DEFORMABLE,51,1)); benchmarks.push_back(new update_geometry ("refit_geometry_100k", RTC_GEOMETRY_DEFORMABLE,159,1)); benchmarks.push_back(new update_geometry ("refit_geometry_1000k_1", RTC_GEOMETRY_DEFORMABLE,501,1)); benchmarks.push_back(new update_geometry ("refit_geometry_100k_10", RTC_GEOMETRY_DEFORMABLE,159,10)); benchmarks.push_back(new update_geometry ("refit_geometry_10k_100", RTC_GEOMETRY_DEFORMABLE,51,100)); benchmarks.push_back(new update_geometry ("refit_geometry_1k_1000" , RTC_GEOMETRY_DEFORMABLE,17,1000)); #if defined(__X86_64__) benchmarks.push_back(new update_geometry ("refit_geometry_120_10000",RTC_GEOMETRY_DEFORMABLE,6,8334)); #endif benchmarks.push_back(new update_geometry ("update_geometry_120", RTC_GEOMETRY_DYNAMIC,6,1)); benchmarks.push_back(new update_geometry ("update_geometry_1k" , RTC_GEOMETRY_DYNAMIC,17,1)); benchmarks.push_back(new update_geometry ("update_geometry_10k", RTC_GEOMETRY_DYNAMIC,51,1)); benchmarks.push_back(new update_geometry ("update_geometry_100k", RTC_GEOMETRY_DYNAMIC,159,1)); benchmarks.push_back(new update_geometry ("update_geometry_1000k_1", RTC_GEOMETRY_DYNAMIC,501,1)); benchmarks.push_back(new update_geometry ("update_geometry_100k_10", RTC_GEOMETRY_DYNAMIC,159,10)); benchmarks.push_back(new update_geometry ("update_geometry_10k_100", RTC_GEOMETRY_DYNAMIC,51,100)); benchmarks.push_back(new update_geometry ("update_geometry_1k_1000" , RTC_GEOMETRY_DYNAMIC,17,1000)); #if defined(__X86_64__) benchmarks.push_back(new update_geometry ("update_geometry_120_10000",RTC_GEOMETRY_DYNAMIC,6,8334)); #endif } Benchmark* getBenchmark(const std::string& str) { for (size_t i=0; iname == str) return benchmarks[i]; std::cout << "unknown benchmark: " << str << std::endl; exit(1); } void plot_scalability() { Benchmark* benchmark = getBenchmark(g_plot_test); //std::cout << "set terminal gif" << std::endl; //std::cout << "set output\"" << benchmark->name << "\"" << std::endl; std::cout << "set key inside right top vertical Right noreverse enhanced autotitles box linetype -1 linewidth 1.000" << std::endl; std::cout << "set samples 50, 50" << std::endl; std::cout << "set title \"" << benchmark->name << "\"" << std::endl; std::cout << "set xlabel \"threads\"" << std::endl; std::cout << "set ylabel \"" << benchmark->unit << "\"" << std::endl; std::cout << "plot \"-\" using 0:2 title \"" << benchmark->name << "\" with lines" << std::endl; for (size_t i=g_plot_min; i<=g_plot_max; i+= g_plot_step) { double pmin = inf, pmax = -float(inf), pavg = 0.0f; size_t N = 8; for (size_t j=0; jrun(i); pmin = min(pmin,p); pmax = max(pmax,p); pavg = pavg + p/double(N); } //std::cout << "threads = " << i << ": [" << pmin << " / " << pavg << " / " << pmax << "] " << benchmark->unit << std::endl; std::cout << " " << i << " " << pmin << " " << pavg << " " << pmax << std::endl; } std::cout << "EOF" << std::endl; } static void parseCommandLine(int argc, char** argv) { for (int i=1; iprint(numThreads,64); } /* skip unknown command line parameter */ else { std::cerr << "unknown command line parameter: " << tag << " "; std::cerr << std::endl; } } } /* main function in embree namespace */ int main(int argc, char** argv) { create_benchmarks(); /* parse command line */ parseCommandLine(argc,argv); if (argc == 1) { size_t numThreads = getNumberOfLogicalThreads(); #if defined (__MIC__) numThreads -= 4; #endif rtcore_intersect_benchmark(RTC_SCENE_STATIC, 501); for (size_t i=0; iprint(numThreads,4); } return 0; } } int main(int argc, char** argv) { try { return embree::main(argc, argv); } catch (const std::exception& e) { std::cout << "Error: " << e.what() << std::endl; return 1; } catch (...) { std::cout << "Error: unknown exception caught." << std::endl; return 1; } }