2010-03-13 2 views
10

구조체를 공부하고 있습니다. 어떤 책은 16 바이트보다 작은 인스턴스 크기를 가진다면 struct를 생성 할 것을 권합니다.구조체가 16 바이트 미만인 경우 구조체가 더 좋은 이유는 무엇입니까?

왜?

답장을 보내 주셔서 감사합니다.

+0

중복 된 http://stackoverflow.com/questions/1082311/why-should-a-net-struct-be-less-than-16-bytes –

+0

또한 http://stackoverflow.com/questions의 속담/2407691/c-struct-design-why-16-byte-recommended-size/2407869 # 2407869 – slugster

답변

28

16 바이트는 하나 또는 두 개의 간단한 이동 명령을 사용하는 대신 컴파일러가 구조체를 메모리 블록으로 복사하기 시작하는 임계 값이기 때문입니다.

컴파일러는 구조체가 작을 때 구조체의 복사를 최적화합니다. 예를 들어 8 바이트 인 구조체는 단일 64 비트 값으로 복사 할 수 있습니다. 16 바이트 구조체는 하나 또는 두 개의 단일 값으로 복사 할 수 있습니다 (프로세서 아키텍처에 따라 다름). 구조가 16 바이트보다 클 때 컴파일러는 더 이상 이동을 최적화하지 않으므로 폴백은 메모리 블록을 복사하는 메서드를 호출하는 것입니다.

(참고 : 16 바이트의 임계 값은 컴파일러 버전에 따라 다를 수 있지만 실제로는 최신 버전에서 그 지점을 넘어서 최적화하려고 시도하지만 최적화 된 코드는 여전히 많은 이동 명령이 될 것입니다 여전히 하나의 이동 작업 인 개체에 대한 참조를 복사하는) 편집

:.

struct 4 : 272 ms. 
struct 8 : 235 ms. 
struct 16 : 317 ms. 
struct 32 : 625 ms. 
struct 64 : 1280 ms. 
struct 128 : 4659 ms. 
struct 256 : 8020 ms. 
: 여기
절반 억 시간 내 64 비트 시스템 복사 구조체에 한 테스트의 결과입니다

16 바이트 미만에서는 시간이 선형이 아니지만 16b ytes는 4 바이트의 4 배이며, 4 배의 시간이 걸리지 않습니다. 16 바이트를 초과하면 시간은 선형이므로 크기가 두 배로 늘어납니다. 그것이 다중 동작을 사용하기 시작하는 곳입니다. 64 바이트를 초과하면 점프가 발생하여 크기가 두 배로 커지면 갑자기 시간이 4 배가됩니다. 그것이 바로 폴백이 사용되기 시작하는 곳입니다.

+0

당신은 윤곽의 관점을 가지고 있습니다 – Ricky

+0

당신의 요점은 어디에서 왔습니까? – Ricky

+0

@Ricky : 나는 몇 년 동안 테스트를 해왔다. 위의 현재 테스트 결과를 추가했습니다. – Guffa

1

정확히 16 바이트는 아니지만 구조체가 값으로 전달되므로 (메서드를 지정하거나 할당 할 때마다 복사되므로) 너무 커서는 안됩니다. 그렇다면 참조로 전달하는 것이 더 저렴합니다.

4 년 후 : 저는 .NET에 대해 거의 알지 못한다고 대답했습니다 (아직도 그것에 대해 많이 알지 못합니다). Guffa의 대답은 "16 바이트보다 많거나 적음"을 처리 할 때 분명 더 정확합니다. 그 크기에서 복사가 중요하지 않아야하기 때문입니다. 내 답변은 거대한 구조체를 만들 때 명심해야 할 부분 일 수 있습니다.

+0

64 비트 포인터는 구조체의 128 비트보다 여전히 저렴합니다. 이 대답은별로 의미가 없습니다. – slugster

+2

"64 비트 포인터가 여전히 128 비트 구조체보다 쌉니다." 왜 그런 말을 해? 포인터를 얻는 것은 일반적으로 .NET에서 값이 비싼 힙 할당 및 가비지 수집을 의미합니다. 포인터를 쓰는 것은 .NET에서 값 비싼 쓰기 장벽을 발생 시킨다는 것을 의미합니다. –

+0

@slugster : 8 바이트 레퍼런스는 16 바이트 구조보다 싸게 복사 될 수 있지만 유용한 레퍼런스는 힙의 객체를 식별해야합니다. 16 바이트 데이터로 힙 객체를 생성하고 백만 번 참조를 복사하는 것은 16 바이트 구조를 백만 번 복사하는 것보다 저렴하지만 16 바이트 객체를 작성하고 참조를 두 번 복사 한 다음 버리면됩니다. 16 바이트 구조를 두 번 복사하는 것보다 훨씬 더 비쌉니다 (또는 아마도 20 번까지도 가능할 것입니다). – supercat

관련 문제