diff --git a/CMakeLists.txt b/CMakeLists.txt index 45fc6de72a..f8a3be499e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -662,9 +662,18 @@ if(UNIX) CHECK_SYMBOL_EXISTS(memalign malloc.h HAVE_MEMALIGN) endif() # TODO: - # - _aligned_malloc() on Win32 # - std::aligned_alloc() C++17 / C11 endif() +elseif(WIN32) + include(CheckIncludeFile) + include(CheckSymbolExists) + + if(OPENCV_ENABLE_MEMALIGN) + CHECK_INCLUDE_FILE(malloc.h HAVE_MALLOC_H) + if(HAVE_MALLOC_H) + CHECK_SYMBOL_EXISTS(_aligned_malloc malloc.h HAVE_WIN32_ALIGNED_MALLOC) + endif() + endif() endif() include(cmake/OpenCVPCHSupport.cmake) diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index eba022d222..05c3ea6a7e 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -80,6 +80,9 @@ endif() if(HAVE_MEMALIGN) ocv_append_source_file_compile_definitions(${CMAKE_CURRENT_SOURCE_DIR}/src/alloc.cpp "HAVE_MEMALIGN=1") endif() +if(HAVE_WIN32_ALIGNED_MALLOC) + ocv_append_source_file_compile_definitions(${CMAKE_CURRENT_SOURCE_DIR}/src/alloc.cpp "HAVE_WIN32_ALIGNED_MALLOC=1") +endif() if(HAVE_VA_INTEL_OLD_HEADER) ocv_append_source_file_compile_definitions("${CMAKE_CURRENT_LIST_DIR}/src/va_intel.cpp" "HAVE_VA_INTEL_OLD_HEADER") endif() diff --git a/modules/core/src/alloc.cpp b/modules/core/src/alloc.cpp index 4b58fb6891..a0def9db2e 100644 --- a/modules/core/src/alloc.cpp +++ b/modules/core/src/alloc.cpp @@ -82,7 +82,7 @@ cv::utils::AllocatorStatisticsInterface& getAllocatorStatistics() return allocator_stats; } -#if defined HAVE_POSIX_MEMALIGN || defined HAVE_MEMALIGN +#if defined HAVE_POSIX_MEMALIGN || defined HAVE_MEMALIGN || defined HAVE_WIN32_ALIGNED_MALLOC static bool readMemoryAlignmentParameter() { bool value = true; @@ -148,6 +148,14 @@ void* fastMalloc(size_t size) return OutOfMemoryError(size); return ptr; } +#elif defined HAVE_WIN32_ALIGNED_MALLOC + if (isAlignedAllocationEnabled()) + { + void* ptr = _aligned_malloc(size, CV_MALLOC_ALIGN); + if(!ptr) + return OutOfMemoryError(size); + return ptr; + } #endif uchar* udata = (uchar*)malloc(size + sizeof(void*) + CV_MALLOC_ALIGN); if(!udata) @@ -170,6 +178,12 @@ void fastFree(void* ptr) free(ptr); return; } +#elif defined HAVE_WIN32_ALIGNED_MALLOC + if (isAlignedAllocationEnabled()) + { + _aligned_free(ptr); + return; + } #endif if(ptr) { diff --git a/modules/core/test/test_misc.cpp b/modules/core/test/test_misc.cpp index 372aab7eb0..67d0a53995 100644 --- a/modules/core/test/test_misc.cpp +++ b/modules/core/test/test_misc.cpp @@ -2,6 +2,7 @@ // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. #include "test_precomp.hpp" +#include namespace opencv_test { namespace { @@ -783,5 +784,18 @@ TEST(Core_Check, testSize_1) } } +TEST(Core_Allocation, alignedAllocation) +{ + // iterate from size=1 to approximate byte size of 8K 32bpp image buffer + for (int i = 0; i < 200; i++) { + const size_t size = static_cast(std::pow(1.091, (double)i)); + void * const buf = cv::fastMalloc(size); + ASSERT_NE((uintptr_t)0, (uintptr_t)buf) + << "failed to allocate memory"; + ASSERT_EQ((uintptr_t)0, (uintptr_t)buf % CV_MALLOC_ALIGN) + << "memory not aligned to " << CV_MALLOC_ALIGN; + cv::fastFree(buf); + } +} }} // namespace