2009-05-13 2 views
6

엄지 손가락의 규칙은 작은 구조체를 값으로 전달하는 것이 좋으며 큰 구조체는 포인터로 처리해야한다는 것입니다.얼마나 큰 구조체를 값으로 효율적으로 전달할 수 있습니까?

제 질문은 정확히이 차단 지점입니까? 구조체를 포인터로 전달하는 것이 더 나은 상태가되기 전에 구조체가 얼마나 커질 수 있습니다.

플랫폼마다 다를 수 있지만 대략적인 견적을 제시 할 수 있습니다. 1 년 또는 2 년 전에 PPC 아키텍처에서이 사실을 파악하려고 노력했는데 놀랍게도 상당량의 데이터를 효율적으로 가치있게 전달할 수 있다는 것을 알았습니다. PPC에있는 많은 수의 레지스터로 인해 10 개의 double 값을 생각해보십시오. By 포인터는 실제로 메모리 안팎으로 더 많은 복사를 포함했습니다.

그러나 나는 지금 나는 인텔에 있고 나는 일이 다를 수 있다고 기대한다. CPU에는 전통적으로 많은 레지스터가 없지만 64 비트 또는 부동 소수점 레지스터에서는 다를 수 있습니다.

+4

다릅니다 .... 벤치 마크해야합니다 ... –

+1

미치가 정확합니다. 알아야 할 유일한 방법은 벤치 마크입니다. 그리고 귀하의 답변은 귀하가 테스트하는 플랫폼에 따라 다릅니다. –

+0

내 문제는 벤치 마크 방법을 올바르게 표시하지 못한다는 것입니다. 나는 간단한 예제가 컴파일러에 의해 너무 쉽게 최적화되고 실제 사용법을 반영하지 않을 것을 두려워한다. 조숙 한 최적화를 수행하는 것은 어리석은 것처럼 보일지 모르지만, 이는 내가 불필요한 어리석은 선택을하고 싶지 않기 때문에 좋은 성능을 발휘하는 데 어려움을 겪어 왔습니다. 내 전체 API 디자인에 영향을 미치므로 나중에이 모든 것을 변경하지 않아도됩니다. –

답변

1

자, 조언을 따르고 포인터와 값을 사용하여 코드를 프로파일하려고했습니다. 나는 또한 어셈블리 코드를 보았다. x86에서의 성능 특성은 PPC와는 상당히 다른 것으로 보입니다. PPC에서 C에 대한 바이너리 인터페이스는 인수가 레지스터에 저장되도록 지정 했으므로 (너무 많이 선택했기 때문에), 64 비트 x86에서도 인수를 스택에 넣어야합니다.

그래서 x86에서 포인터를 전달하는 것이 항상 더 빠를 것입니다. 그러나 나는 컴파일러가 인라인하기를 매우 열망하고 있다는 것을 알아 차렸다. 그래서 어떤 방식으로했는지는 중요하지 않습니다. 그래서 결론은 당신에게 편리한 어떤 통과를 사용하는 것입니다.

나는 값의 복사본을 다루는 것이 다소 안전하기 때문에 가치에 의해 전달된다고 생각한다. 내 테스트 케이스는 4 개의 double로 구성된 구조체였다. 그래서 대부분의 플랫폼에서 32 바이트가된다.

4

웹을 검색하면 참조 및 값을 전달하기위한 바이트 크기에 대한 몇 가지 지침을 찾을 수 있습니다. 나는 거의 그것을 믿지 않을 것입니다. 할 수있는 유일한 방법은

그것은

이 문제가 있음을 100 % 알 수있는 유일한 방법입니다 프로필에 특정 구조체가 문제가는 알고있다.

naysayers가 점프하기 전에. 예. 명백한 사례가 있습니다. 예를 들어 100 명의 멤버를 말하면 값으로 구조체를 전달하지 않습니다. 그러나 그것은 성능 문제가 아니며, 스택 공간 문제에 더 많은 영향을 미칩니다.

+0

Downvote. 이것은 답변이 아닙니다. 웹 검색을 사람들에게 말하지 마십시오. 사실을 게시하고 참조하십시오. –

0

테스트에서 정렬이 수행하는 부분을 무시하지 마십시오. 수레 또는 복식을 전달하고 구조가 적절한 경계에 정렬되지 않은 경우 프로세서는 값의 일부를 가져 와서 이동시킨 다음 나머지를 OR 연산하여 저장합니다. 나는 현대 컴파일러가 DTRT (구조체를 선언 할 때 구조체를 정렬함으로써)라고 생각하지만 공간을 최적화하는 경우 문제가 될 수 있습니다. 나는 펜티엄 프로 이후 86 아치에있는 낮은 수준의 코딩을하지 않은 것처럼

흠, 지금은 그것에 대해 생각,

0

어떤 컴파일러 월 ..., 에누리이 걸릴 최적의 크기 결정을하십시오. 필자가 정확하게 기억한다면, TI28xx 컴파일러는 구조체가 특정 크기를 초과하면 패스를 값으로 전달하여 참조로 전달합니다.

2

는 C++에서 const 참조 때문에 performanceis 본질적으로 결코 악화로 다음 목록에 모든하지를 전달하는 규칙이있다. 예외 목록은 다음과 같습니다

  • 초등학교 유형 (int 등),
  • 포인터,
  • 빈 유형 (태그 유형),
  • 기능과 같은 유형 (펑) 및
  • 반복자.

C에 직접 적용 할 수 있는지 확실하지 않지만 (C의 명백한 유형은 제외) 비슷한 지침이 적용될 수 있습니다.

+0

C++을 프로그래밍 할 때이 패턴을 따르지만 엄격하게 말해서 항상 최적이라고 확신하지는 않습니다. 내가 아는 한 const MyClass & var는 const 포인터로 구현됩니다. 작은 물체 (예 : 2-3 배)의 경우 포인터로 전달하는 것이 값 전달보다 느립니다. –

+0

물론 포인터에 대한 액세스는 오버 헤드를 유발하지만 프로세서 제조업체는 포인터의 필요성을 인식하고 있습니다. 따라서 예방 조치를 취합니다. AMD 최적화 가이드 (예 : explicity)는 포인터가 이러한 용도를 염두에두고 개발 되었기 때문에 여기서 포인터를 사용하도록 조언합니다. 긴 이야기는 짧습니다 : 작은 구조체의 경우에도 포인터는 값별로 전달하는 것보다 빠를 수 있습니다. 인라이닝은 물론이 동작을 추가로 수정할 수 있습니다. –

+0

게시 한 예외 목록의 "공식적인"출처가 있습니까? 나는 참고로 초등 유형을 전달하는 것이 합리적이라는 질문을 던지기까지했다. –

-1

일반적으로 기본 유형은 값으로 전달하고 다른 모든 것은 참조로 전달합니다. 그것은 엄지 손가락의 규칙입니다.

+4

질문은 규칙에 관한 것이 아니라 성과에 관한 것입니다. – stepancheg

관련 문제