성능을 고려해야 할 가장 좋은시기는 언제입니까?


45

소프트웨어 개발 배경에서 왔습니다. 소프트웨어 개발주기 동안 일반적으로 기능 및 작동중인 제품에 중점을 둡니다. 개발이 끝나면 코드 최적화 및 성능 개선이 시작됩니다.

이제 문제는 게임 개발에서 모든 단일 코드 행의 성능에 대해 생각해야합니까?

그렇게하면 디자인 패턴과 깨끗한 코드가 그리워집니다. 게임 개발 산업에 모범 사례가 있는지 궁금합니다.


8
조기 최적화에 대한이전 질문에 대한 토론이 유용 할 수 있습니다.
DMGregory

10
처음에. 프로젝트가 진행되면서 성능은 더욱 나빠질 것입니다.
Tomáš Zato

10
당신이 온 소프트웨어 개발 배경은 건전하지 않습니다. 디자인은 모든 분야에서 성능을 고려해야합니다. 네트워크 왕복 횟수, 데이터베이스 쿼리 수 및 크기, 사용 된 메모리 양 등 어떤 엔지니어링 분야에서이 작업을 수행하는지는 중요하지 않습니다. 성능을 계획하지 않으면 성능 실패를 계획합니다.
Jon Watte

1
모두. 그만큼. 시각. 항상 시간을 들여서 시간과 지루한 작업을 절약하고 이미 필요한 것보다 코드를 더욱 최적화하여 매우 시원하고 괴상한 작업을 수행하게됩니다. 그곳에서 재미가 시작됩니다.
Yates

6
"고려"성능 은 사용자 가 있는 제품 을 만들기로 결정한 날에 발생해야 합니다 . 사용자는 최소한의 성능을 기대하며 충족되지 않으면 제품이 작동하지 않습니다. 성능에는 비용이 있고 제품에는 예산이 있습니다. 허용 가능한 최소 성능이 예산보다 많은 경우 프로젝트가 실패 합니다. 백일이 아니라 첫날에 생각하는 것이 현명합니다.
Eric Lippert

답변:


90

성능 엔지니어링

  • 공급 업체 권장 사항을 따르십시오.
  • 올바른 데이터 구조를 사용하십시오.
  • 올바른 사용 패턴을 구현하십시오.
  • 바보 같은 짓을하지 마십시오.

최적화

  • 이미 작성된 코드가 느리게 실행되면 코드를 측정하고 이유를 확인하고 코드를 빠르게 만드는 데 필요한 것을 구현하십시오.

조기 최적화

  • 측정하지 않고 빠르거나 느린 것에 대해 가정하고 코드를 설계하고 작성하는 방법에 이러한 가정을 구축하십시오.

이 세 가지는 동일하지 않습니다 .

특히 성능 엔지니어링은 처음 부터 수행해야하는 작업 이며 실제 측정을 기반으로하기 때문에 조기 최적화와 동일하지 않습니다 . 이 경우 하드웨어 작동 방식 및 사용 패턴이 빠르거나 느린 경험에 대한 경험과 권장 사항을 바탕으로합니다.

성능에 대한 엔지니어의 실패는 전체 재 설계가 필요하고 잘못된 것을 발견 할 때마다 다시 작성하는 것만 큼 나쁜 결과를 초래할 수 있습니다.

예를 들어, 모든 GPU 공급 업체는 모든 프레임에서 GPU의 리드 백을 수행하는 것이 좋습니다. 리드 백하지 않도록 코드를 설계하는 것은 조기 최적화아닙니다 .


28
이것을 언급 해 주셔서 대단히 감사합니다. 개발자는 항상 조기 최적화의 악을 공표하여 조언을 구해야하지만, 경험이 부족한 개발자는 뉘앙스를 이해하지 못하는 경우가 많습니다. 처음부터 올바르게 설계하십시오. 그것은 조기 최적화가 아닙니다. 나는 당신이 쓰는 모든 줄에 대해 성능을 의식해야한다고 말합니다. 개발자는 어리석은 일을하지 않도록 모범 사례를 알고 있어야합니다. 즉, 최적화로 자신을 마비해서는 안됩니다. 먼저 실행해야 할 내용을 파악한 다음 속도를 늦추는 것에 중점을 둡니다.
AC

2
@AC 또한 좋은 디자인은 처음부터 시작하는 데 시간이 걸릴 수 있다고 말하고 싶지만 결국에는 더 빨리 완료되었음을 의미 할 것입니다. 이는 필요할 경우 최적화에 더 많은 시간이 걸리는 것을 의미합니다. 내 경험 (단일 반 완료 솔로 취미 프로젝트로 백업)은 일단 프로젝트가 충분히 커지면 많은 시간을 소비합니다. 1) "이미 존재하는 모든 것에 이것을 어떻게 짜야합니까?" 2) "Damnit, 내가 일주일 전에 작성한 코드는 완벽하게 맞아 다음에하고 싶은 것과 전혀 작동하지 않습니다." 좋은 디자인 (내가하지 않은)은 두 가지 모두를 도와줍니다.
Arthur

5
성능을 제대로 엔지니어링하지 못하면 디자인을 비관적으로 생각할 수 있습니다. 그래서, 경우 조기 최적화는 모든 악의 뿌리입니다 ,의 메이크업 무엇을 조기 pessimization을 ? ; P
ninjalj

1
@Arthur "최적화를위한 시간이 더 남았습니다"? 최적화 된 노력으로 최적의 효과를 얻을 수 있도록 제한된 개발 리소스 (및 워크 플로)를 최적화하는 것도 좋은 방법입니다! 또한, 우리는 우리가 스택 오버플로에 적합하지 않다는 것을 알고 있지만, 우리가 최적화를 말하고 있으며 파레토 원칙 이 아직 답변에 언급되지 않았다는 사실에 놀랐습니다. "퍼센트"라는 단어조차 보이지 않습니다!
AC

1
우수한 성능을 위해 데이터 구조를 설계 할 때는 컴퓨터가 효율적으로 수행 할 수 있고 수행 할 수없는 것을 알아야합니다. 예를 들어, 배열을 반복하는 최신 CPU는 특히 SSE / AVX를 사용하여 컴파일러가 자동 벡터화 할 수 있도록 설정하는 경우 엄청난 양의 힘을 가할 수 있습니다. (예 : xy 쌍 구조체 또는 xyz 트리플이 아닌 x 좌표 배열 및 y 좌표 배열 사용. 일부 링크, 특히 Insomniac Games (GDC 2015)의 SIMD에 대해서는 stackoverflow.com/tags/sse/info 를 참조하십시오
Peter Cordes

22

적절한시기에 최적화를 수행하려면 머신 속도가 느리고 사용하십시오. 소규모 상점의 경우 출퇴근시 느린 랩톱을 사용하고 사무실에서는 빠른 데스크톱을 사용하는 것이 좋습니다. 추가 혜택으로, 한 사람의 상점이라면 전체 빌드 환경을 올바르게 백업해야합니다.

느린 기계를 사용하면 성능을 개선해야 할시기를 알 수 있습니다.

게임 개발에서 모든 단일 코드 행의 성능에 대해 생각해야합니까?

절대적으로하지. 코드 라인의 성능은 일반적으로 모든 종류의 개발과 관련이 없습니다. 선이 아니라 알고리즘 및 복잡성 측면에서 생각해야합니다 . 대부분의 경우 적절한 프로그래밍은 코드 줄을 최적화하여 속도를 약 2 배 높일 수 있지만 올바른 알고리즘을 선택하면 수천에서 수백만 사이의 요소가 발생합니다.

조기 최적화에 대한 이야기는 실제로 최적화가 나쁜 것이 아닙니다. 사람들이 옳은 것을 최적화하지 못하는 것에 관한 것입니다. 시간은 최적화해야 할 변수 중 하나이며, 30 밀리 초마다 한 번 호출되는 함수를 "최적화"하는 데 시간을 낭비하지 않고 실행하는 데 100 마이크로 초가 소요됩니다.

다시 말해, "더 빠른"것을 만드는 것은 의미가 없습니다. 당신의 목표는 "충분히 빠릅니다". 이미 "충분히 빠른"것을 "빠르게"만드는 것은 시간 낭비이며 여전히 "빠른"것이 아닌 "빠른"을 만드는 것은 여전히 ​​너무 느리다는 것을 의미합니다. "빠른"은 관련이 없으며 "충분히 빠른"만 관련됩니다.


1
알고리즘은 솔루션의 절반에 불과하므로 데이터 구조를 올바르게 사용하는 것도 매우 중요합니다. 또한 멀티 스레딩 및 64 비트 컴파일을 도입 할 수 있도록 미리 계획하십시오. 모든 경우에 필요한 것은 아니지만 때로는 이러한 기능이 중요하기 때문에 계획되지 않은 경우 소급 적용하기가 쉽지 않습니다. (이 두 가지 문제로 고통받는 일부 게임을 알고 있습니다.).
hoffmale 2016 년

릴리스 빌드보다 훨씬 느린 디버그 빌드로 많은 개발이 수행됩니다. 즉, 게임을 수용 가능한 속도로 실행하는 데 필요한 것보다 훨씬 빠른 시스템이 개발에 필요합니다.
Jack Aidley

캐시 액세스 패턴도 중요하며 10 또는 100의 차이를 만들 수 있습니다. 예를 들어 순진 행렬 곱하기 (대형 행렬의 경우)를 고려하십시오. 행 주요 행렬의 한 열을 반복하는 것은 끔찍합니다. 예를 들어, 이 Q & A 는 끔찍한 액세스 패턴을 수정하기 위해 루프 앞에 조옮김을 추가 할 때 동일한 알고리즘 복잡성에 대해 13 perf 차이를가집니다. (캐시 및 SIMD에 대해 더 많은 관심을 갖는 최적화 된 BLAS 라이브러리에서 10 이상의 다른 요소를 얻을 수 있습니다 ...)
Peter Cordes

9

아니요, 모든 라인이 성능과 관련이있는 것은 아니기 때문에 모든 라인 을 점검 할 필요는 없습니다 . 주로 라인이 얼마나 자주 실행되는지에 달려 있습니다. 실행하는 데 1ms가 걸리는 코드 섹션은 게임 시작시 한 번 실행될 때 완전히 관련이 없으며 매 프레임마다 실행될 때 시청할 가치가 있으며 각 프레임마다 모든 게임 객체에 대해 실행되는 경우 반드시 최적화해야합니다.

또한 어떤 종류의 게임을 개발 하느냐에 달려 있습니다. 그래픽이 강렬한 3D 슈팅 게임을 개발할 때는 레트로 스타일 RPG 게임을 프로그래밍 할 때보 다 훨씬 성능을 인식해야합니다.

결국 가장 좋은 조언은 테스트, 테스트, 테스트입니다. 실제 게임에서 예상되는 것보다 약간 더 많은 내용을 화면에 표시하는 현실적인 테스트 장면을 게임에 구축하십시오. 대상 사양의 하단에있는 하드웨어에서 테스트하십시오. 성능이 예상 한대로되어 있는지 확인하십시오. 악화되면 프로파일 러를 사용하여 병목 현상을 찾으십시오.


3

최소한 "가장 병목이 될 수 있는가? 그렇다면 병을 고치려면 어떻게해야합니까?"라고 충분한 노력을 기울여야합니다.

일반적으로, 이것은 올바른 방향인지 파악하는 데 소요되는 시간 / 자원과 잘못된 결정을 실행 취소하는 데 소요 된 시간 / 자원 간의 균형을 포함합니다.

아파트를 개조하는 것과 다소 비슷하다고 생각하십시오. 일부 결정에는 지속적인 영향이있을 수 있습니다 ( "후프, 냉장고는 더 이상 큐비에 맞지 않습니다." "후프, 화장실에 넣고 싶은 물은 없습니다"). 예를 들어 건물의 구조적 안정성에 영향을 줄 수 있습니다.

또는 다시 말해서 구석에 몸을 맡기지 마십시오. 또는 적어도 당신이 구석에 자신을 백업 할 때 알고 있고 다시 구석에 있는지 확인하십시오. 예를 들어 :

  • 게임 업데이트 속도를 그래픽 프레임 속도로 묶고 있습니까?
  • 동기 저장을 강제하고 있습니까?
  • 비결정론을 강요합니까?

1

게임의 주요 목표는 대상 최소 사양 머신 (및 가능한 최대로드 시간 등)의 대상 프레임 속도를 충족시키는 것입니다.

그렇게하기 위해, 당신은 모든 라인 후에 걱정할 필요가 없습니다.

특정 전략, 알고리즘 또는 컨테이너를 선택할 때마다 조기에 걱정해야합니다. 부적절한 디자인 결정을하여 목표를 달성하는 것이 사실상 불가능하다면, 나중에 할 수있는 최적화는 아무 소용이 없습니다.

다음으로, 어떤 것이 병렬이거나 병렬화 될 때마다 걱정해야합니다 . 다른 이유가 없다면 그래픽은 게임이기 때문에 게임은 매우 평행합니다.
따라서 병렬은 "스레드"뿐만 아니라 그래픽 API, 디스크 액세스 또는 네트워크를 의미합니다. 동기화가 잘못되거나 비동기식 API를 전혀 사용하지 않아서 병렬로 쉽고 기본적으로 병렬로 실행할 있는 것을 가질 기회를 놓치면 다른 방법으로 최적화 할 수있는 것보다 더 많은 것을 잃게됩니다.
당신은 또한 뭔가 를 걱정할 필요가병목 현상이나 포장 마차 또는 스케일링 방해로 잘 알려져 있습니다. 예를 들어 렌더 상태 전환, 호출 그리기, GPU에서 다시 읽거나 파일 열기 등이 있습니다.

마지막으로, 테스트가 완료되면 테스트 에서 목표 프레임 속도를 충족 하지 않는 것으로 최적화해야합니다. 시간의 90 %를 차지하는 가장 큰 병목 현상을 찾아서 최적화하십시오. 이것으로 충분하지 않으면 초를 가장 크게 찾으십시오.
목표를 달성하면 축하합니다. 계속해서 잊어 버리세요.


0

현실을 얻으십시오. 대답은 단순히 전혀 아니요입니다. 토론이 없습니다.

주요 문제는 당신이 묻는 방법입니다.

게임 개발에서 모든 단일 코드 행의 성능에 대해 생각해야합니까?

구성 화면과 같은 것에서도 의미합니까? 작은 1kb 최대 구성 파일에 대한 일회성 파서처럼? 진심이야?

코드의 시간이 얼마나 중요한지는 중요하지 않습니다. 모든 단일 회선이 시간 결정적인 단일 소프트웨어는 없습니다. 아무데도.

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