From 95354f044c39d07424eee9448592c5c483da0076 Mon Sep 17 00:00:00 2001 From: pratham-mcw Date: Tue, 23 Sep 2025 18:18:10 +0530 Subject: [PATCH] Merge pull request #27596 from pratham-mcw:core-kmeans-loop-unroll core: ARM64 loop unrolling in kmeans to improve Weighted Filter performance #27596 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - This PR improves the performance of the Weighted Filter function from the ximgproc module on Windows on ARM64. - The optimization is achieved by unrolling two performance-critical loops in the generateCentersPP function in modules/core/src/kmeans.cpp, which is internally used by the Weighted Filter function. - The unrolling is enabled only for ARM64 builds using #if defined(_M_ARM64) guards to preserve compatibility and maintain performance on other architectures. **Performance Improvements:** - Improves execution time for Weighted Filter performance tests on ARM64 without affecting other platforms. image --- modules/core/src/kmeans.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/core/src/kmeans.cpp b/modules/core/src/kmeans.cpp index f5a5bc5c6c..f01785d353 100644 --- a/modules/core/src/kmeans.cpp +++ b/modules/core/src/kmeans.cpp @@ -131,7 +131,15 @@ static void generateCentersPP(const Mat& data, Mat& _out_centers, KMeansPPDistanceComputer(tdist2, data, dist, ci), (double)divUp((size_t)(dims * N), CV_KMEANS_PARALLEL_GRANULARITY)); double s = 0; - for (int i = 0; i < N; i++) + int i = 0; + #if CV_ENABLE_UNROLLED + for (; i + 7 < N; i += 8) + { + s += tdist2[i + 0] + tdist2[i + 1] + tdist2[i + 2] + tdist2[i + 3] + + tdist2[i + 4] + tdist2[i + 5] + tdist2[i + 6] + tdist2[i + 7]; + } + #endif + for (; i < N; i++) { s += tdist2[i]; }