C #과 같은 관리되는 언어로 게임을 작성할 때의 일반적인 함정은 무엇입니까? [닫은]


66

C #과 같은 관리되는 언어로 PC 용 게임을 작성할 때 어떤 함정이 있었으며 어떻게 해결 했습니까?


이 질문은 게임과 관련된 내용이 거의 없기 때문에 Stack Overflow에서 더 잘 묻습니다.
크리스 개럿

31
@Chris : 매우 동의하지 않음 : 질문은 게임을 구체적으로 언급합니다! 16ms마다 업데이트를 푸시해야 할 때 발생하는 문제는 대부분의 데스크톱 응용 프로그램에서 발생하는 문제와 매우 다릅니다.
앤드류 러셀

문제는 분명하지 않습니다. Java와 C #은 두 가지 모두에 적용 할 수있는 매우 일반적인 조언에 대해서만 충분히 다릅니다. 지금까지의 모든 대답은 C #이었습니다. 언급되지 않은 대상 플랫폼-좋은 조언은 장치에 따라 다를 수 있습니다 (예 : 휴대폰, zune, xbox 프로그래밍, PC 프로그래밍과 다름). 관리되는 언어 자체가 "함정"이라고 누군가가 대답 한 것은 충분히 넓은 질문이었습니다.
paulecoyote

@ paulecoyote : C #에 대해서만 질문하기 위해 질문으로 변경했습니다. 또한 언급 된 특정 플랫폼이 없으므로 PC에 관한 것입니다.
Michael Klement

@Michael은 플랫폼이 구현 방식이 많이 다르기 때문에 위험한 가정이라고 가정하고 Windows를 구체적으로 언급하고 "like"와 "Java"를 모두 삭제하는 것이 좋습니다.
paulecoyote

답변:


69

Java에 대해 많이 알지 못하므로 .net 개발자의 관점에서 왔습니다.

가장 큰 것은 쓰레기입니다. Windows의 .net 가비지 수집기는 환상적인 작업을 수행하며 대부분의 경우 아기가 앉지 않아도 도망 갈 수 있습니다. xbox / winPhone7에서는 다른 문제입니다. 몇 프레임마다 실속되면 가비지 수집으로 인해 문제가 발생할 수 있습니다. 현재 1MB 할당마다 트리거됩니다.

쓰레기 처리에 대한 몇 가지 팁이 있습니다. 대부분의 경우 실제로 걱정할 필요는 없지만 언젠가는 편리 할 수 ​​있습니다.

  • GC.GetTotalMemory()화면에 내용 을 그립니다. 이것은 게임이 사용하는 할당 된 바이트의 근사치입니다. 거의 움직이지 않으면 괜찮습니다. 빠르게 진행되면 문제가있는 것입니다.
  • 모든 객체 를 미리 할당하십시오 . 게임이 시작되기 전에 모든 것을 할당하지 않으면, 많은 할당량을 칠 때마다 실속합니다. 할당도없고 컬렉션도 없습니다. 저것과 같이 쉬운.
  • 로드 후 GC.Collect ()를 호출하십시오. 대부분의 큰 할당이 완료된 것을 알고 있다면 시스템에 알려주는 것만으로도 좋습니다.
  • GC.Collect()모든 프레임을 호출하지 마십시오 . 가비지와 그 이상을 유지하는 것이 좋은 생각처럼 보일 수 있지만 가비지 수집보다 나쁜 것은 가비지 수집 이상이라는 것을 기억하십시오.
  • 쓰레기가 나오는 곳을 찾으십시오. 사용하지 않고 문자열을 연결하는 것과 같은 일반적인 원인이 있습니다 StringBuilder( StringBuilder마법의 탄환이 아니며 할당을 유발할있습니다!) . 사용 foreach사용 컬렉션을 통해 루프를 IEnumerable또한 모르게 쓰레기를 만들 수 있습니다 인터페이스를 (예를 들어, foreach (EffectPass pass in effect.CurrentTechnique.Passes)일반적인 하나입니다)
  • CLR 메모리 프로파일 러 와 같은 도구를 사용 하여 메모리가 할당되는 위치를 찾으십시오. 이 도구를 사용하는 방법에 대한 많은 자습서가 있습니다.
  • 게임 플레이 중 할당 위치를 알면 객체 풀링과 같은 트릭을 사용하여 할당 횟수를 줄일 수 있는지 확인하십시오.
  • 다른 모든 방법이 실패하면 컬렉션을 더 빠르게 실행하십시오! 컴팩트 프레임 워크의 GC는 더 이상 사용되지 않는 객체를 파악하기 위해 코드의 모든 참조를 따릅니다. 적은 참조를 사용하여 코드를 리팩터링하십시오!
  • IDisposable관리되지 않는 리소스가 포함 된 클래스 에서 사용해야 합니다. 이를 사용하여 GC가 자체적으로 확보 할 수없는 메모리를 정리할 수 있습니다.

고려해야 할 다른 것은 부동 소수점 성능입니다. .Net JITer는 상당한 양의 프로세서 별 최적화를 수행하지만 SSE 또는 다른 SIMD 명령어 세트를 사용하여 부동 소수점 연산 속도를 높일 수는 없습니다. 이로 인해 게임의 C ++과 C #간에 속도 차이가 크게 발생할 수 있습니다. 모노를 사용하는 경우 활용할 수있는 특별한 SIMD 수학 라이브러리가 있습니다.


완전히 동의하십시오. "더 적은"플랫폼에서 가비지 콜렉터 구현은 완전한 가비지 인 것 같습니다.
Krisc

그러나 "힙 객체를 사전에 할당"에 대한 귀하의 진술과 관련하여 좋은 게시물은 가치 유형에 대한 진실
Justin

코드를 최적화 할 때 최적화하려는 플랫폼을 이해하는 것이 좋습니다. 그것은 실제로 값 유형 / 참조 유형에 대한 의견이 아니 었습니다. 오래 살았던 객체는 스택에 없을 가능성이 큽니다. 로드 시간에 가능한 한 많은 할당량을 얻는 것이 게임 플레이 중에 마법의 1MB 장벽에 부딪치지 않도록하는 것입니다. xna가 대상으로하는 모든 .net 구현은 깔끔한 보증을 제공합니다. 시간에 가깝게 할당 된 객체는 공간이 가까워 성능에 좋을 수 있습니다.
Cubed2D

또한 xbox의 현재 컴팩트 프레임 워크는 인라인 메소드 호출에 알레르기가 있음을 언급하지 않은 것처럼 보입니다. 그래도 최악의 성능 시나리오를 유지하십시오. 수학 방법의 참조 버전을 사용하면 그대로 추한 것처럼 보입니다!
Cubed2D

10

Tipical 성능 함정은 게임 디자인 / 개발에서 가비지 수집기를 고려하지 않습니다. 가비지를 너무 많이 생성하면 게임에서 "딸꾹질"이 발생할 수 있으며, 이는 GC가 상당히 오랫동안 실행될 때 발생합니다.

C #의 경우 값 개체와 "using"문을 사용하면 GC의 압력이 완화 될 수 있습니다.


3
또한 할당 / 무거운 무거운 루프를 방금 완료했거나 여유주기가있는 경우 가비지 콜렉터에 명시 적으로 실행하도록 지시 할 수 있습니다.
BarrettJ

16
using진술은 가비지 수집과 관련이 없습니다! IDisposable관리되지 않는 리소스 (예 : 가비지 수집기에서 처리하지 않는 리소스)를 해제 하기위한 개체 입니다.
앤드류 러셀

9

C #에서 게임을 작성하면서 발생한 가장 큰 문제는 괜찮은 라이브러리가 없다는 것입니다. 내가 찾은 대부분은 직접 포트이지만 불완전하거나 마샬링에 대한 성능 저하가 큰 C ++ 라이브러리의 래퍼입니다. (저는 OGRE 라이브러리의 MOgre 및 Axiom 및 Bullet 물리 라이브러리의 BulletSharp에 대해 구체적으로 말하고 있습니다)

실제로 언어를 느리게 만드는 요소 (마셜 링, 가비지 수집)에 대해 잘 이해하고 있다면 관리되는 언어 (통역과 구별됨-Java와 C #은 더 이상 실제로 해석되지 않음)가 모국어만큼 빠를 수 있습니다. 실제 문제는 라이브러리 개발자가 아직 깨닫지 못했다는 것입니다.


그것은 C #과 Java가 해석되는 대신 관리되는 것에 대한 좋은 지적입니다 ... 더 정확하게하기 위해 내 질문을 편집했습니다 :)
Michael Klement

2
마샬링은 일반적으로 성능 병목 현상이지만 성능에 큰 영향을 미치지 않으면 서 관리되지 않는 메모리에 직접 매핑 할 수있는 유형 인 블 리터 블 유형을 인식하는 데 도움이됩니다. msdn.microsoft.com/ko-kr/library/75dwhxf7.aspx
Sean Edwards

8

다른 사람들이 말했듯이 GC 수집 일시 중지가 가장 큰 문제입니다. 객체 풀을 사용하는 것이 일반적인 솔루션 중 하나입니다.


4

C #과 Java는 해석되지 않습니다. 그것들은 JIT 이후 네이티브 코드만큼 빠르거나 중간 정도의 중간 바이트 코드로 컴파일됩니다.

내가 찾은 가장 큰 함정은 사용자 경험에 직접적인 영향을 미치는 리소스를 확보하는 것입니다. 이 언어들은 C ++처럼 결정 론적 마무리를 자동으로 지원 하지 않습니다. 예상치 못한 상황에서는 메시가 파괴되었다고 생각한 후에 씬에 떠 다니는 메시와 같은 것들이 생길 수 있습니다. (C #은 IDisposable을 통해 결정 론적 마무리를 달성 하지만 Java가 무엇을하는지 잘 모르겠습니다.)

그 외에도 관리되는 언어는 실제로 게임이 요구하는 것보다 필요한 성능을 처리 할 수있는 능력이 훨씬 뛰어납니다. 잘 작성된 관리 코드는 잘못 작성된 원시 코드보다 훨씬 빠릅니다.


예, 메모 덕분에 이미 해석 / 관리 된 것을 수정했습니다.;) 또한 메쉬가 장면에 떠 다니는 것이 좋습니다. GC 문제에 대해 생각할 때 그렇게 생각하지 않았다 ...
Michael Klement

1
IDisposable시간이 중요하고 관리되지 않는 리소스를 결정적으로 정리할 수 있지만 마무리 나 가비지 수집기에 직접적인 영향을 미치지는 않습니다.
Sam Harwell

4

Java 나 C #은 해석되지 않습니다. 둘 다 네이티브 머신 코드로 컴파일됩니다.

게임과 게임 모두에서 가장 큰 문제는 게임 플레이 중에 가비지 수집을하지 않는 방식으로 코딩해야한다는 것입니다. 이를 달성하기 위해 뛰어 넘어야하는 후프의 수는 처음에이를 사용하는 것의 이점보다 훨씬 큽니다. 응용 프로그램이나 서버 프로그래밍에 이러한 언어를 재미있게 사용하는 대부분의 기능은 게임 프로그래밍에서 사용하지 않아야합니다. 그렇지 않으면 게임 플레이가 중단되고 가비지 수집으로 인해 일시 중지됩니다.


가비지 콜렉션은 적어도 C #에서는 합리적으로 잘 처리 될 수 있으므로 거래 차단기라고 말할 수는 없습니다. 적절한 스레딩 및 프로그램 상태 인식을 통해 성능 문제를 피할 수 있습니다. 여전히 고려해야 할 또 다른 사항이며 관리되는 언어를 조금 덜 관리합니다.
Karantza

4
.NET 4에서 가비지 수집기는 3 세대 개체 모두에 대한 백그라운드 수집을 지원합니다. 이는 게임에서 가비지 콜렉션의 성능 영향을 효과적으로 최소화해야합니다. 관련 링크 : geekswithblogs.net/sdorman/archive/2008/11/07/…
Mike Strobel

가비지 수집가는 진화하고 있으며 Mike Strobel이 지적한 것처럼 일부는 이미 이러한 함정을 거의 제거하는 생산 단계에 있습니다.
Sam Harwell

2
C #이나 Java는 네이티브 머신 코드로 컴파일되지 않습니다. C #은 MSIL로 컴파일하고 Java는 바이트 코드로 컴파일합니다. 가비지 콜렉션은 "긴"일시 중지를 제공하지 않지만 "히컵"을 제공 할 수 있습니다.
Cloudanger

2

이와 같은 언어로 게임을 만들거나 XNA, TorqueX 엔진 등과 같은 도구를 사용하여 내가 볼 수있는 한 가지 큰 함정은 다음과 동등한 게임을 만드는 데 필요한 전문 지식을 갖춘 훌륭한 사람들로 구성된 팀을 찾기가 어렵다는 것입니다. C ++ 및 OpenGL / DirectX에서 사람들을 찾기가 매우 쉽습니다.

크거나 잘 연마 된 작은 게임을 밀어내는 데 사용되는 대부분의 도구와 파이프 라인이 C ++로 작성되었으며, 내가 할 수있는 모든 공식 개발 키트를 아는 한, 게임 개발 산업은 여전히 ​​C ++에서 매우 급격한 발전을 이루었습니다. XBox, PS3 및 Wii는 C ++와의 호환성으로 만 릴리스됩니다. (XBox 툴 세트는 요즘 더 잘 관리 될 수 있습니다. 누군가 더 알고 있습니까?)

콘솔 용 게임을 지금 개발하고 싶다면 XBox와 X #을 XBox Live Indie Games라는 게임 라이브러리의 한 쪽에서 만 얻을 수 있습니다. 콘테스트 등에서 우승 한 일부 사람들은 게임을 실제 XBox Live Arcade로 이식하기 위해 선택됩니다. PC를위한 게임을 만드는 계획 외에.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.