RenderKit / embree

Embree ray tracing kernels repository.
Apache License 2.0
2.37k stars 389 forks source link

Voronoi / knn timing #415

Closed syedharoonalam closed 1 year ago

syedharoonalam commented 1 year ago

Hi guys, I have been doing some preliminary testing for nearest neighbor validation using Embree library. I am also comparing results with C++ ANN library.

I am using the following pipeline to build bvh for 360 points:

//global deceleration rtcSetSceneFlags( m_scene, RTC_SCENE_FLAG_DYNAMIC | RTC_SCENE_FLAG_ROBUST ); rtcSetSceneBuildQuality( m_scene, RTC_BUILD_QUALITY_LOW );

//local deceleration rtcNewGeometry //5μs (using RTC_GEOMETRY_TYPE_USER) rtcSetGeometryBuildQuality //1μs (using RTC_BUILD_QUALITY_LOW) rtcSetGeometryUserPrimitiveCount //503μs rtcSetGeometryUserData //0μs rtcSetGeometryBoundsFunction //7μs rtcCommitGeometry //1μs rtcAttachGeometry //3μs rtcReleaseGeometry //0μs rtcCommitScene //30μs

However, when using ANN, it builds kdtree in 141μs.

Kindly advise if further optimization is possible when building bvh. Thank you

svenwoop commented 1 year ago

That benchmark looks wrong, the rtcSetGeometryUserPrimitiveCount function does essentially nothing and should not consume 503us. Also if you benchmark just a single build you risk to just benchmark memory allocation time. Set the RTC_SCENE_FLAG_DYNAMIC and benchmark (rtcCommitGeometry, rtcCommitScene) in a loop.

syedharoonalam commented 1 year ago

Hi Please find below the updated benchmark for 360 points with RTC_SCENE_FLAG_DYNAMIC

ann point array allocation: 3μs duration ann tree build: 137μs ann cleanup: 20μs

rtcNewGeometry //10μs rtcSetGeometryBuildQuality //1μs rtcSetGeometryUserPrimitiveCount //0μs rtcSetGeometryUserData //2μs rtcSetGeometryBoundsFunction //0μs rtcCommitGeometry //first iteration: 0μs rtcCommitGeometry //second iteration: 0μs rtcAttachGeometry //1μs rtcReleaseGeometry //1μs rtcCommitScene //first iteration: 566μs rtcCommitScene //second iteration: 9μs

In our case, the point count will always change on the execution of the above pipeline. Which means as per docs rtcCommitScene has to be called every time? I have also tried with rtcJoinCommitScene and I see similar results.

Please note I am using Embree 3.9.0 and TBB: 4.4.6

Kindly advise.

svenwoop commented 1 year ago

In our case, the point count will always change on the execution of the above pipeline. Which means as per docs rtcCommitScene has to be called every time?

Correct, if the points or point count changes you have to invoke rtcCommitGeometry (for the changed geometry) and rtcCommitScene (for the scene containing that geometry) each time before tracing more rays.

syedharoonalam commented 1 year ago

We are mostly using this to find the nearest neighbor points. But I was wondering isn't this possible to run the following once:

constructor():
rtcNewGeometry 
rtcAttachGeometry with the scene
rtcCommitScene 
update():
//each time points change we just do:
rtcSetGeometryUserPrimitiveCount
rtcSetGeometryUserData
rtcSetGeometryBoundsFunction
rtcCommitGeometry
destructor():
rtcReleaseGeometry 
rtcDeatachGeometry

Otherwise is there any way to optimize the original pipeline further?

svenwoop commented 1 year ago

If you change the points or point counts then you have to invoke rtcCommitScene before doing further queries on the scene.