저는 지금 공유 메모리로 작업합니다.
나는 이해할 수 없다 alignof
하고 alignas
.
cppreference 가 명확하지 않습니다. alignof
"alignment"를 반환하지만 "alignment"는 무엇입니까? 정렬 할 다음 블록을 위해 추가 할 바이트 수? 패딩 사이즈? 스택 오버플로 / 블로그 항목도 명확하지 않습니다.
사람이 명확하게 설명 할 수 alignof
와 alignas
?
저는 지금 공유 메모리로 작업합니다.
나는 이해할 수 없다 alignof
하고 alignas
.
cppreference 가 명확하지 않습니다. alignof
"alignment"를 반환하지만 "alignment"는 무엇입니까? 정렬 할 다음 블록을 위해 추가 할 바이트 수? 패딩 사이즈? 스택 오버플로 / 블로그 항목도 명확하지 않습니다.
사람이 명확하게 설명 할 수 alignof
와 alignas
?
답변:
정렬은 값의 첫 번째 바이트가 저장 될 수있는 메모리 위치에 대한 제한입니다. (프로세서의 성능을 향상시키고 특정 정렬이있는 데이터에서만 작동하는 특정 명령어의 사용을 허용하는 데 필요합니다. 예를 들어 SSE는 16 바이트로 정렬되고 AVX는 32 바이트로 정렬해야합니다.)
16의 정렬은 16의 배수 인 메모리 주소가 유일한 유효한 주소임을 의미합니다.
alignas
필요한 바이트 수로 강제 정렬합니다. 2 : 1, 2, 4, 8, 16, 32, 64, 128, ...의 거듭 제곱으로 만 정렬 할 수 있습니다.
#include <cstdlib>
#include <iostream>
int main() {
alignas(16) int a[4];
alignas(1024) int b[4];
printf("%p\n", a);
printf("%p", b);
}
예제 출력 :
0xbfa493e0
0xbfa49000 // note how many more "zeros" now.
// binary equivalent
1011 1111 1010 0100 1001 0011 1110 0000
1011 1111 1010 0100 1001 0000 0000 0000 // every zero is just a extra power of 2
다른 키워드
alignof
매우 편리합니다.
int a[4];
assert(a % 16 == 0); // check if alignment is to 16 bytes: WRONG compiler error
하지만 당신은 할 수 있습니다
assert(alignof(a) == 16);
assert(alignof(b) == 1024);
실제로 이것은 단순한 "%"(모듈러스) 연산보다 더 엄격합니다. 사실 우리는 1024 바이트로 정렬 된 것이 반드시 1, 2, 4, 8 바이트로 정렬된다는 것을 알고 있지만
assert(alignof(b) == 32); // fail.
더 정확하게 말하자면, "alignof"는 어떤 것이 정렬 될 때 가장 큰 2의 거듭 제곱을 반환합니다.
또한 alignof는 기본 데이터 유형에 대한 최소 정렬 요구 사항을 미리 알 수있는 좋은 방법입니다 (아마도 문자의 경우 1, 부동의 경우 4를 반환합니다).
여전히 합법적 :
alignas(alignof(float)) float SqDistance;
16으로 정렬 된 항목은 16의 배수 인 다음 사용 가능한 주소에 배치됩니다 (마지막으로 사용 된 주소에서 암시 적 패딩이있을 수 있음).
sizeof
, alignof
단지에 적용 할 수 있습니다 type-id
.
alignof()
(및 대응는 alignas()
) 그래서 런타임 오버 헤드, 컴파일 시간에 평가되지?
struct
하다 구조체의 및 회원 static
. 특히 Clang과 같은 컴파일러에서는 alignas
보다 훨씬 까다 __attribute__((aligned))
롭습니다.
정렬은 패딩이 아닙니다 (정렬 요구 사항을 충족하기 위해 패딩이 도입되는 경우도 있음). C ++ 유형의 intrisic 속성입니다. 표준에 넣으려면 ( 3.11[basic.align]
)
객체 유형에는 해당 유형의 객체가 할당 될 수있는 주소에 제한을 두는 정렬 요구 사항 (3.9.1, 3.9.2)이 있습니다. 정렬은 주어진 객체가 할당 될 수있는 연속 주소 사이의 바이트 수를 나타내는 구현 정의 정수 값입니다. 개체 유형은 해당 유형의 모든 개체에 대해 정렬 요구 사항을 부과합니다. 더 엄격한 정렬은 정렬 지정자 (7.6.2)를 사용하여 요청할 수 있습니다.
struct X { char a; char b}
정상적인 시스템에서 크기 2 및 정렬 요구 사항 1이 있습니다 (문자는 모든 주소에 할당 될 수 있으므로 모든 주소에 할당 가능)
alignof(std::max_align_t)
있는 에서 최대 값을 얻습니다 16
(-m32 또는 -m64 컴파일 여부에 관계없이),하지만 다음과 같이 더 엄격하게 만들 수 있습니다.alignas
정렬은 메모리 주소와 관련된 속성입니다. 주소 X가 Z에 정렬되면 x는 Z의 배수, 즉 X = Zn + 0입니다. 여기서 중요한 것은 Z가 항상 2의 제곱이라는 것입니다.
정렬은 메모리 주소의 속성으로, 2의 거듭 제곱 모듈로 숫자 주소로 표현됩니다. 예를 들어, 주소 0x0001103F 모듈로 4는 3입니다.이 주소는 4n + 3으로 정렬됩니다. 여기서 4는 선택한 전원을 나타냅니다. 2. 주소의 정렬은 선택한 2의 거듭 제곱에 따라 달라집니다. 동일한 주소 모듈로 8은 7입니다. 주소가 Xn + 0이면 X에 정렬된다고합니다.
위의 문은 Microsoft C ++ 참조에서 찾을 수 있습니다.
데이터 항목이 크기에 맞는 주소로 메모리에 저장되면 해당 데이터 항목은 자연스럽게 정렬 된다고합니다. 되고 그렇지 않으면 잘못 . 예를 들어, 크기가 4 바이트 인 정수 변수가 4로 정렬 된 주소에 저장되면 변수가 자연적으로 정렬된다고 말할 수 있습니다. 즉, 변수의 주소는 4의 배수 여야합니다.
컴파일러는 항상 오정렬을 피하기 위해 노력합니다. 단순 데이터 유형의 경우 주소는 변수 크기 (바이트)의 배수가되도록 선택됩니다. 컴파일러는 또한 자연적인 정렬과 접근을위한 구조의 경우 적절하게 채 웁니다. 여기에서 구조는 구조에있는 서로 다른 데이터 항목의 최대 크기로 정렬됩니다.
struct abc
{
int a;
char b;
};
여기서 구조 abc는 1 바이트 (char 멤버의 크기)보다 분명히 큰 int 멤버의 크기 인 4에 정렬됩니다 .
정렬
이 지정자는 structure, class 등과 같은 사용자 정의 유형을 2의 거듭 제곱 인 특정 값으로 정렬하는 데 사용됩니다.
정렬
이것은 구조 또는 클래스 유형이 정렬되는 값을 가져 오는 일종의 연산자입니다. 예 :
#include <iostream>
struct alignas(16) Bar
{
int i; // 4 bytes
int n; // 4 bytes
short s; // 2 bytes
};
int main()
{
std::cout << alignof(Bar) << std::endl; // output: 16
}