정렬된 메모리를 얻을 수 있는 최고의 크로스 플랫폼 방법
여기 내가 Visual Studio와 GCC와 메모리를 정렬할 때 사용하는 코드가 있습니다.
inline void* aligned_malloc(size_t size, size_t align) {
void *result;
#ifdef _MSC_VER
result = _aligned_malloc(size, align);
#else
if(posix_memalign(&result, align, size)) result = 0;
#endif
return result;
}
inline void aligned_free(void *ptr) {
#ifdef _MSC_VER
_aligned_free(ptr);
#else
free(ptr);
#endif
}
이 코드는 일반적으로 괜찮습니까?나는 또한 사람들이 사용하는 것을 본 적이 있습니다._mm_malloc
,_mm_free
. 대부분의 경우에는 SSE/AVX를 사용해야 합니다.그 기능들을 일반적으로 사용할 수 있습니까?그러면 내 코드가 훨씬 간단해질 겁니다.
마지막으로, 메모리 정렬을 위한 나만의 기능을 쉽게 만들 수 있습니다(아래 참조).정렬된 메모리를 얻을 수 있는 다양한 공통 기능(많은 기능이 하나의 플랫폼에서만 작동함)은 왜 이렇게 많습니까?
이 코드는 16바이트 정렬을 합니다.
float* array = (float*)malloc(SIZE*sizeof(float)+15);
// find the aligned position
// and use this pointer to read or write data into array
float* alignedArray = (float*)(((unsigned long)array + 15) & (~0x0F));
// dellocate memory original "array", NOT alignedArray
free(array);
array = alignedArray = 0;
참조: http://www.songho.ca/misc/alignment/dataalign.html 및 표준 라이브러리를 사용해서만 정렬된 메모리를 할당하는 방법은 무엇입니까?
편집 : 신경쓰는 분이 계실까봐 아이겐(Eigen/src/Core/util/Memory.h)에서 aligned_malloc() 기능 아이디어를 얻었습니다.
편집: 방금 발견했습니다.posix_memalign
MinGW에 대해 정의되지 않았습니다.하지만,_mm_malloc
는 Visual Studio 2012, GCC, MinGW 및 Intel C++ 컴파일러에서 작동하므로 일반적으로 가장 편리한 솔루션인 것 같습니다.또한 자체적으로 사용해야 합니다._mm_free
함수, 일부 구현에서 포인터를 전달할 수 있지만_mm_malloc
정석대로free
/delete
.
특수 기능을 호출해서 프리를 해도 괜찮기만 하면 접근 방법은 괜찮습니다.난 당신의 것을 할겁니다.#ifdef
s는 반대로 표준별 옵션에서 시작하여 플랫폼별 옵션으로 돌아갑니다.예를들면
- 한다면
__STDC_VERSION__ >= 201112L
사용하다aligned_alloc
. - 한다면
_POSIX_VERSION >= 200112L
사용하다posix_memalign
. - 한다면
_MSC_VER
정의되어 있습니다. Windows 항목을 사용합니다. - ...
- 만약 다른 모든 것이 실패한다면, 그냥 사용하세요.
malloc
/free
SSE/AVX 코드를 비활성화합니다.
할당된 포인터를 에 전달하려면 문제가 더 어렵습니다.free
; 이는 모든 표준 인터페이스에서 유효하지만 Windows에서는 유효하지 않으며 레거시의 경우에도 유효하지 않습니다.memalign
일부 유닉스 계열 시스템이 가지고 있는 기능입니다.
당신이 제안하는 첫번째 기능은 확실히 잘 작동할 것입니다.
"홈브루" 기능도 작동하지만, 값이 이미 정렬되어 있으면 15바이트만 낭비한다는 단점이 있습니다.때로는 문제가 되지 않을 수도 있지만, OS가 낭비 없이 올바르게 할당된 메모리를 제공할 수 있는 것은 당연합니다. 또한 256바이트 또는 4096바이트로 정렬해야 하는 경우 "alignment-1"바이트를 추가함으로써 많은 메모리를 낭비할 위험이 있습니다.
다음은 user2093113의 샘플을 수정한 것으로, 직접 코드가 나를 위해 만들어지지 않았습니다(void* unknown size).또한 연산자 new/delete보다 우선하는 템플릿 클래스에 추가하여 할당 및 호출 배치를 새로 할 필요가 없습니다.
#include <memory>
template<std::size_t Alignment>
class Aligned
{
public:
void* operator new(std::size_t size)
{
std::size_t space = size + (Alignment - 1);
void *ptr = malloc(space + sizeof(void*));
void *original_ptr = ptr;
char *ptr_bytes = static_cast<char*>(ptr);
ptr_bytes += sizeof(void*);
ptr = static_cast<void*>(ptr_bytes);
ptr = std::align(Alignment, size, ptr, space);
ptr_bytes = static_cast<char*>(ptr);
ptr_bytes -= sizeof(void*);
std::memcpy(ptr_bytes, &original_ptr, sizeof(void*));
return ptr;
}
void operator delete(void* ptr)
{
char *ptr_bytes = static_cast<char*>(ptr);
ptr_bytes -= sizeof(void*);
void *original_ptr;
std::memcpy(&original_ptr, ptr_bytes, sizeof(void*));
std::free(original_ptr);
}
};
다음과 같이 사용합니다.
class Camera : public Aligned<16>
{
};
아직 이 코드의 교차 플랫폼성을 테스트하지 않았습니다.
만약 당신이 컴파일러를 지원한다면, C++11은 다음을 추가합니다.std::align
런타임 포인터 정렬을 수행하는 함수입니다.다음과 같이 자신만의 malloc/free를 구현할 수 있습니다(테스트되지 않음).
template<std::size_t Align>
void *aligned_malloc(std::size_t size)
{
std::size_t space = size + (Align - 1);
void *ptr = malloc(space + sizeof(void*));
void *original_ptr = ptr;
char *ptr_bytes = static_cast<char*>(ptr);
ptr_bytes += sizeof(void*);
ptr = static_cast<void*>(ptr_bytes);
ptr = std::align(Align, size, ptr, space);
ptr_bytes = static_cast<void*>(ptr);
ptr_bytes -= sizeof(void*);
std::memcpy(ptr_bytes, original_ptr, sizeof(void*));
return ptr;
}
void aligned_free(void* ptr)
{
void *ptr_bytes = static_cast<void*>(ptr);
ptr_bytes -= sizeof(void*);
void *original_ptr;
std::memcpy(&original_ptr, ptr_bytes, sizeof(void*));
std::free(original_ptr);
}
그러면 원래 포인터 값을 비워둘 필요가 없습니다.이것이 100% 휴대용인지는 확실하지 않지만, 만약 그렇지 않다면 누군가 나를 고쳐주길 바랍니다!
여기 제 2센트입니다.
temp = new unsigned char*[num];
AlignedBuffers = new unsigned char*[num];
for (int i = 0; i<num; i++)
{
temp[i] = new unsigned char[bufferSize +15];
AlignedBuffers[i] = reinterpret_cast<unsigned char*>((reinterpret_cast<size_t>
(temp[i% num]) + 15) & ~15);// 16 bit alignment in preperation for SSE
}
언급URL : https://stackoverflow.com/questions/16376942/best-cross-platform-method-to-get-aligned-memory
'programing' 카테고리의 다른 글
jquery가 있는 div의 하단 위치 찾기 (0) | 2023.10.04 |
---|---|
테이블의 현재 값을 사용하여 문 업데이트 (0) | 2023.10.04 |
WordPress 서버에서 논스 토큰을 새로 고치지 않음 (0) | 2023.10.04 |
Wordpress와 Spring MVC의 통합 (0) | 2023.10.04 |
jQuery 페이드 디스플레이 없이 꺼집니까? (0) | 2023.10.04 |