Speed up per-class NMS for segment, pose and obb with a SIMD suppression loop - #470
Speed up per-class NMS for segment, pose and obb with a SIMD suppression loop#470onuralpszr wants to merge 2 commits into
Conversation
Signed-off-by: Onuralp SEZER <onuralp@ultralytics.com>
|
👋 Hello @onuralpszr, thank you for submitting a
For more guidance, please refer to our Contributing Guide. Don't hesitate to leave a comment if you have any questions. Thank you for contributing to Ultralytics! 🚀 |
UltralyticsAssistant
left a comment
There was a problem hiding this comment.
🔍 PR Review
Made with ❤️ by Ultralytics Actions
Reviewed both changed files and the NMS callers. The SIMD suppression control flow matches the scalar implementation for normal finite boxes, but detect now incurs additional per-image allocation and copying without gaining a faster suppression algorithm. This is a bounded performance regression in the detect hot path.
💬 Posted 1 inline comment
- 📝 LOW
src/postprocessing.rs:567This adds avoidable hot-path overhead for detect: the previous implementation sortedcandidatesin place and built the SIMD SoA directly, whereas this now copies every retained candidate intonms_input;nms_per_class_simdthen allocates an index vector, performs an indirect sort, and copies the coordinates again. With the defaultmax_detand the existing 10x pre-cap, this affects up to 3,000 candidates per image even though detect already had the same SIMD suppression loop. Please prese…
| } | ||
| } | ||
| } | ||
| let nms_input: Vec<([f32; 4], f32, usize)> = candidates |
There was a problem hiding this comment.
📝 LOW: This adds avoidable hot-path overhead for detect: the previous implementation sorted candidates in place and built the SIMD SoA directly, whereas this now copies every retained candidate into nms_input; nms_per_class_simd then allocates an index vector, performs an indirect sort, and copies the coordinates again. With the default max_det and the existing 10x pre-cap, this affects up to 3,000 candidates per image even though detect already had the same SIMD suppression loop. Please preserve the detect-side representation or provide a shared sorted-input/SoA entry point so detect can reuse its existing setup without the extra tuple materialization.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Signed-off-by: Onuralp SEZER <onuralp@ultralytics.com>
🛠️ PR Summary
Made with ❤️ by Ultralytics Actions
🌟 Summary
Added an eight-lane SIMD suppression loop for capped per-class NMS to speed up axis-aligned box filtering used by segment, pose, and OBB inference paths.
📊 Key Changes
nms_per_class_simd, which processes candidate boxes in groups of eight usingwide::f32x8.max_detdetections.nms_per_class_cappedto use the SIMD implementation.🎯 Purpose & Impact