Farseer 2.x는 왜 임시가 아닌 회원으로 임시 저장합니까? (.그물)


10

업데이트 :이 질문은 Farseer 2.x에 관한 것입니다. 최신 3.x는 이것을하지 않는 것 같습니다.

나는 현재 Farseer Physics Engine을 꽤 광범위하게 사용하고 있으며, 많은 임시 값 유형 을 클래스의 멤버 로 저장 하고 스택에 기대하지 않는 것으로 보입니다 .

다음은 Body클래스 의 예입니다 .

private Vector2 _worldPositionTemp = Vector2.Zero;

private Matrix _bodyMatrixTemp = Matrix.Identity;
private Matrix _rotationMatrixTemp = Matrix.Identity;
private Matrix _translationMatrixTemp = Matrix.Identity;

public void GetBodyMatrix(out Matrix bodyMatrix)
{
    Matrix.CreateTranslation(position.X, position.Y, 0, out _translationMatrixTemp);
    Matrix.CreateRotationZ(rotation, out _rotationMatrixTemp);
    Matrix.Multiply(ref _rotationMatrixTemp, ref _translationMatrixTemp, out bodyMatrix);
}

public Vector2 GetWorldPosition(Vector2 localPosition)
{
    GetBodyMatrix(out _bodyMatrixTemp);
    Vector2.Transform(ref localPosition, ref _bodyMatrixTemp, out _worldPositionTemp);
    return _worldPositionTemp;
}

수동 성능 최적화처럼 보입니다. 그러나 이것이 어떻게 성능을 향상시킬 수 있는지 보지 못합니까? (물건을 크게 만들어서 다칠 것이라고 생각되면).

답변:


6

.NET에서 값 유형이 스택에 저장되어 할당 비용을 최소화하지만 초기화 비용을 제거하지는 않습니다.

이 경우 하나 또는 두 개의 임시 행렬을 사용하는 함수 집합이 있으므로 호출 당 16-32 부동 소수점이 초기화됩니다. 이것이 중요하지 않은 것처럼 보일 수 있지만, 방법이 자주 사용되는 경우 (예 : 프레임 당 수천 번), 전체 오버 헤드는 의미있는 영향을 줄 수 있습니다. 그러한 기술이 모든 그러한 방법에 걸쳐 체계적으로 사용된다면, 제거되는 오버 헤드가 상당 할 수있다.

이러한 기술을 사용하면 객체 별 수준에서 스레드 안전성을 제공하는 기능이 제거되지만 일반적으로 이러한 세부적인 수준으로 보장하는 것은 현명하지 않습니다.


확실합니까? 내가 가진 생각 중 하나는 생성자를 호출하지 않는 것입니다. 그러나 값 유형의 경우 모든 멤버를 설정하거나 out매개 변수 로 전달하려는 경우 기본 매개 변수가없는 생성자를 포함하여 생성자를 호출 할 필요가 없습니다 . 이 규칙의 요점은 컴파일러가 메모리 제로화를 건너 뛸 수 있도록 확실히 확신합니다. ( 스택 포인터를 이동하는 것이 정말 느린가요?)
Andrew Russell

놀랍지 않습니까? 불행하게도, 생성 된 IL을 검사하면 임시 행렬이 초기화됩니다. 몇 가지 빠른 테스트를 통해 멤버-템프 버전이 ~ 10-15 % 빠릅니다.
Jason Kozak

1
나는 기절했다 . "XNA 프레임 워크 성능 이해"(GDC2008)에서 Shawn Hargreaves는 다음과 같이 말합니다. "[JIT]는 일반적으로 다음을 알아낼 것입니다. 0으로 초기화하려면 ' " . 내 정보가 어디에서 오는가. 하지만 지금 다시 듣기에, 그는 단지 "보통"말했다. 프레젠테이션의 바로 다음 단계는 JIT가 디버거가 연결된 상태에서 다르게 작동하여 성능에 영향을 미친다는 것입니다 (어떻게 테스트 했습니까?). 또한 그는 여기서 JIT에 대해 이야기하고 있으므로 IL은 "좋은"상태를 유지합니다 (확인 가능성?).
앤드류 러셀

IL은 Reflector를 통해 검사되었으며 테스트는 Release에 내장 된 IDE 외부에서 실행되었습니다 (Windows에서는 더 이상 테스트 할 CC 멤버십이 없음)
Jason Kozak

1
이를 바탕으로-회원 임시 회원을 만드는 것이 더 나은지 (그리고 얼마나 더 나은지) 궁금한지 궁금합니다 static. 예를 들어, BodyFarseer 의 클래스에는 약 73 개의 플로트에 해당하는 "불필요한"멤버가 있습니다.
앤드류 러셀

-1

좋은 질문. 나는 꽤 예리한 C # / .NET 사람이며 약간의 성능 너트이며 다소 이상한 디자인 결정처럼 보입니다. 나에게 가장 먼저 나오는 것은이 코드가 스레드 안전하지 않다는 것입니다. 그것이 물리 시스템에서 문제인지는 모르겠지만 방법 범위 밖에서 임시 데이터를 저장하는 것은 종종 재난의 요리법입니다.

솔직히, 타사 프레임 워크에서 이러한 종류의 코드를 정기적으로 만나면 다른 프레임 워크를 찾으려고 노력할 것입니다.


3
실제로 질문에 대답하지 않습니다.
Brian Ortiz

그래, 내가 할 수있는 최선은 그가 미쳤다는 것을 확인하는 것입니다. 그런 식으로 코딩되는 것이 실제로 이점이없는 것 같습니다. 진정한 의도를 찾는 유일한 것은 코드를 작성한 사람에게 물어 보는 것입니다 :).
Mike Strobel 1

고마워, 마이크 나는 원래 개발자가 내가 아닌 미친 사람이라고 의심하기 시작했다. 그러나 그것은 항상 확인하는 데 도움이됩니다.)
Andrew Russell

스레드 안전은 특히 SIMD 명령어를 사용하지 않는 플랫폼에 대해 FP 계산 무거운 라이브러리를 작성할 때 제공하는 비용이 많이 드는 보증 일 수 있습니다.
Jason Kozak

-1

360의 GC는 기본적으로 고가의 GEN 2 콜렉션 만 수행하므로 임시 오브젝트와 같이 모든 프레임을 작성하고 제거하는 임시 변수는 전체 콜렉션이 실행되도록하여 성능이 매우 빠르게 저하됩니다.

나는 그들이 그 물건을 재사용하고 그것을 수집하지 않기 위해이 방법을했다고 의심합니다.


1
이것은 나에게도 발생했지만 임시 멤버는 값 유형 인 것처럼 보이므로 어쨌든 관리 힙에 할당되지 않습니다.
Mike Strobel

2
맞습니다. 그러나 그들이 반원 인 경우에만 가능합니다. 로컬 (메소드 범위) 인 경우 스택에 할당됩니다. 문제는 그들이 단순히 그 길을 가지 않은 이유입니다.
Mike Strobel

1
@Blair-MSDN ( msdn.microsoft.com/en-us/library/bb203912.aspx ) 에 따르면 Xbox360은 .NET Compact Framework를 사용합니다. GC의 차이점은 그와 관련이있는 것 같습니다. 그래서 그 문제에 대한 추가 연구를 위해 추구합니다.
Logan Kincaid

1
@Blair : @Logan Kincaid가 정확합니다. CF의 가비지 콜렉터는 일반 프레임 워크와 다르게 작동합니다. XNA Game Studio 3.0 Unleashed의 주제에 대해 좋은 이야기가 있습니다. 그러나이 책은 곧 4.0 릴리스로 구식이 될 것입니다.
Steven Evers

1
@Blair : 360 (및 CF를 통해 대상으로 지정된 대부분의 장치)의 제한된 메모리 환경으로 인해 Mark & ​​Sweep GC가 사용됩니다. 결과적으로 많은 작은 할당이 수집을 트리거하며 수집 시간은 참조 수와 관련이 있습니다. 자세한 내용은 여기 : download.microsoft.com/.../Mobility/…
Jason Kozak
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.