std :: vector를 만드는 현대적인 접근 방식으로 정렬 된 메모리 할당


11

다음과 같은 질문은 답변이 오래된 그러나, 관련 및 사용자의 코멘트 마크 Glisse은 충분히 논의되지 않을 수 있습니다이 문제에 대한 17 ++ C 이후 새로운 접근 방식이 있습니다 제안합니다.

SIMD에 대해 정렬 된 메모리가 올바르게 작동하면서 여전히 모든 데이터에 액세스하려고합니다.

Intel에서 유형의 float 벡터를 만들고 __m256크기를 8 배 줄이면 정렬 된 메모리가 제공됩니다.

예 : std::vector<__m256> mvec_a((N*M)/8);

약간 해킹 된 방식으로 벡터 요소에 대한 포인터를 플로팅하여 개별 플로트 값에 액세스 할 수 있습니다.

대신, std::vector<float>올바르게 정렬 된 것을 선호 하므로 __m256segfaulting없이 다른 SIMD 유형에 로드 할 수 있습니다 .

Align_alloc을 살펴 보았습니다 .

이것은 올바르게 정렬 된 C 스타일 배열을 제공 할 수 있습니다.

auto align_sz = static_cast<std::size_t> (32);
float* marr_a = (float*)aligned_alloc(align_sz, N*M*sizeof(float));

그러나에 대한 방법을 잘 모르겠습니다 std::vector<float>. 의 std::vector<float>소유권을 부여하는 marr_a 것은 가능하지 않은 것 같습니다 .

커스텀 할당자를 작성해야한다는 제안을 보았지만 많은 작업처럼 보이며 현대 C ++에서 더 나은 방법이 있습니까?


1
segfaulting이 없거나 ...을 사용할 때 캐시 라인 분할로 인한 잠재적 저하가 없습니다 _mm256_loadu_ps(&vec[i]). 기본 튜닝 옵션, GCC는 참고 있지만 ( 분할 256 비트로드 / 저장 - 보장되지 정렬 vmovups XMM / vinsertf128에. 그래서이 있습니다 사용하는 장점 _mm256_load을 통해 loadu당신이 걱정하는 경우 어떻게 GCC에 코드를 컴파일 누군가 잊어 경우에 사용 -mtune=...또는 -march=옵션.)
Peter Cordes

답변:


1

벡터를 포함한 표준 C ++ 라이브러리의 모든 컨테이너 에는 컨테이너의 할당자를 지정 하는 선택적 템플릿 매개 변수 있으며 실제로는 자신 의 컨테이너 를 구현하는 데 많은 작업이 필요하지 않습니다.

class my_awesome_allocator {
};

std::vector<float, my_awesome_allocator> awesomely_allocated_vector;

할당자를 구현하는 약간의 코드를 작성해야하지만 이미 작성한 것보다 더 많은 코드는 아닙니다. 당신 ++ 17 지원-C를 사전에 필요하지 않은 경우에만 구현해야 할당 ()할당 해제 () 를의, 방법.


또한 전문화가 필요합니다allocator_traits
NathanOliver

1
이것은 사람들이 C ++의 성가신 농구대를 뛰어 넘기 위해 복사 / 붙여 넣기 할 수있는 예를 들어 정식 답변에 좋은 장소 일 수 있습니다. (bonus는 std :: vector가 일반적인 braindead C ++ 대신 항상 제자리에 재 할당 할 수있는 방법이 있다면 지적합니다.) 물론 이것은 vector<float, MAA>유형과 호환 vector<float>되지 않습니다. 않는 것도 .push_back일반에 std::vector<float>이 할당없이 컴파일은 새로운 할당을 복사 최소한으로 정렬 된 메모리에 그리고 새 / 삭제는) / aligned_alloc와 호환 무료로하지 않습니다 수 있습니다.
피터 코르

1
할당 자에서 반환 된 포인터가 std::vector의 배열 의 기본 주소로 직접 사용된다는 보장이 없다고 생각 합니다. 예를 들어, std::vector값 범위 이전에 메모리에 end / capacity / allocator를 저장하는 할당 된 메모리에 대한 하나의 포인터를 사용 하는 구현을 상상할 수 있습니다. 할당 자에 의한 정렬을 쉽게 망칠 수 있습니다.
Dietmar Kühl

1
std::vector그것을 제외하고는 보장합니다. 그것이 그것을 위해 사용하는 것입니다. 아마도 여기에서 C ++ 표준이 무엇을 지정하는지 검토해야합니다.
Sam Varshavchik

1
> 또한 전문화해야합니다 allocator_traits. 아닙니다. 준수 할 할당자를 구현하기 만하면됩니다.
Andrey Semashev
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.