What is PVS Studio

PVS Studio

https://pvs-studio.com/en/
“PVS‑Studio is a static analyzer on guard of code quality, security (SAST), and code safety”
홈페이지에 적혀있는 문구 그대로 보면 코드 정적 분석 툴로 코드 퀄리티와 보안을 위해 사용할 수 있는 툴입니다.

C, C++과 Java 코드를 분석하는 툴로 다른 정적 분석 툴로는 Cppcheck, Clang Static Analyzer, SonarQube 등이 있습니다.
PVS Studio는 클라우드 제품은 없어보이고 설치형 프로그램으로 CI에 붙여서 사용하거나 코드 에디터에 설정하고 사용할 수 있습니다.

PVS-Studio for Visual Studio-PVS Studio blog

정적 코드 분석 툴로 TS(TypeScript)나 자바스크립트 앱을 제작할때 사용하는 TSLint, ESLint와 비슷하다고 볼 수 있겠네요.
실제로 빌드 및 프로그램이 실행할 때에 문제가 없을 수는 있지만 정적 코드 분석 결과 문제가 있을 요소는 미리 수정하는게 좋겠죠.

PVS Studio 기본 설명

https://youtu.be/4Fy-JTYzEs0

사실 기본 설명은 위에 정적 코드 분석 툴 정도로 다 설명이 될 수 있다고 생각합니다.
정적 코드 분석 -> 분석 코드 Warning 확인 -> 수정 -> 코드 개선의 흐름이 정적 코드 분석 툴을 사용하는 흐름이겠죠.

분석 코드 Warning 몇가지를 살펴보고 넘어가겠습니다.
Warnings: https://pvs-studio.com/en/docs/warnings/

  • V501. Identical sub-expressions to the left and to the right of ‘foo’ operator.
    • 왼쪽, 오른쪽 동일한 표현식이 있음. -> “유의미한 표현식을 사용하지 않았네. 수정해라” warning으로 볼 수 있겠네요.
  • V502. The ‘?:’ operator may not work as expected. The ‘?:’ operator has a lower priority than the ‘foo’ operator.
    • ? 연산자의 활용이 적절하지 않게 되어있음. 말 그대로 ? 연산자가 적절히 사용되었는지 확인하고 수정하라는 warning.
  • V503. Nonsensical comparison: pointer < 0.
    • 포인터 비교가 잘못된 코드가 있음. 포인터가 아닌 다른 것을 비교해야한다는 warning으로 이해할 수 있습니다.

위 처럼 Warning에 따라 수정하고 코드를 개선할 수 있는 서비스로 이해해볼 수 있겠습니다.

https://stackshare.io/stackups/pvs-studio-vs-sonarqube
stackshare라는 서비스의 장단점 비교 서비스를 보았을 때 SonarQube와 인지도 차이가 크지만
PVS Studio도 C++ 개발하거나 게임 개발에 사용해볼만한 프로그램으로 사용되긴하는 것 같습니다. 😃
(SonarQube가 인지도가 높아 PVS Studio랑 어떤 차이가 있는지 확인차 살펴보았는데 PVS Studio는 인지도가 역시 낮았네요)

PVS Studio 가이드 문서 살펴보기

공식 가이드 문서: https://pvs-studio.com/en/docs/
블로그: https://pvs-studio.com/en/blog/posts/

마무리

게임 개발을 하면서 코드 분석툴은 어떤 것들이 있고 그중에 PVS Studio는 뭘까 싶어 한번 찾아보게되었네요.
기본적으로 PVS Studio는 정적 코드 분석 툴로 분석한 코드는 개발자들이 확인하고 개선해나가야하는 중간 도우미 같은 친구이긴합니다.
Warning을 다 해결한다고 다 좋은 코드는 아니지만 안정성, 품질을 신경쓰고 있는 코드로 볼 수는 있겠다는 생각이듭니다.

FileOpenLog, FileOpenOrder란?

FileOpenLog, FileOpenOrder

참고 문서: https://docs.unrealengine.com/4.27/ko/Basics/Projects/Packaging/

언리얼 엔진에서 패키지 생성 및 로딩하는 것과 연관이 있는 내용입니다.

참고 문서에서 언급한 내용으로는 아래와 같습니다.

“로드 시간 단축을 위해서는 .pak 파일 순서를 잘 지정하는 것이 중요합니다. .pak 파일 최적의 순서를 지정하는 데 도움을 드리기 위해, UE4 에서는 데이터 애셋의 필요 순서를 알아내어 더욱 빠른 로딩 패키지를 제작하기 위한 툴 세트가 제공됩니다. 개념적으로, 이 프로세스는 프로파일 주도형 최적화와 비슷합니다.”

언리얼 서밋 세션도 있어서 참고해보면,
https://youtu.be/KJUVH_KzLj8?si=QRG7h2Mim5f0KGOD&t=2135

테스트 빌드를 실행할 때에 -fileopenlog 파라미터를 적용해서 실행하고 로그 파일을 빌드시 사용하는 것 입니다. (파일은 {project}/Build/WindowsNoEditor/FileOpenOrder/ 에 위치함)

이 최적화는 Disk보다는 Flash Drive에서 효과적이라고 하네요.
(예시: Disk=HDD, Flash Drive=SSD, USB 드라이브)

언리얼 서밋 세션에서 공유한 예시 수치로는 5.9s → 4.6s, 약 23%가 감소한 수치를 보여줬습니다.
로그를 얻기 위해 실제 유저가 플레이하는 것 처럼 플레이하더라도 많은 게임 데이터를 포함해서 플레이를 하기는 어렵기에 어느정도 감안하고 최적화한다고 봐야할 것 같네요.

마무리

FileOpenLog라는 용어가 일반적인 용어일 줄 알았는데 실제로 사용하는 곳은 언리얼엔진 정도인 것 같습니다.
파일오픈로그(오더) 용어 그대로 파일이 열리는 순서를 최적화해서 로딩 시간을 개선하는 방법, 방법을 위한 파일 정도로 이해하면 좋을 것 같네요.

(Game Dev Study) Grahpics - RenderDoc

RenderDoc이란?

https://renderdoc.org/

그래픽 작업, 렌더링 최적화를 위한 프로파일링으로 사용할 수 있는 디버거 툴로 사이트에서 설명하는 내용을 가져와보면 다음과 같습니다.

RenderDoc is a free MIT licensed stand-alone graphics debugger that allows quick and easy single-frame capture and detailed introspection of any application using Vulkan, D3D11, OpenGL & OpenGL ES or D3D12 across Windows, Linux, Android, or Nintendo Switch™.
→ 요약해보면 오픈소스 그래픽 디버거로 쉬운 프레임 캡처와 상세 분석(검사)을 할 수 있는 툴입니다.

RenderDoc은 Github에서 소스를 공개하고 있으며 빌드는 홈페이지에서 다운로드 받을 수 있습니다.

Source: https://github.com/baldurk/renderdoc
Download: https://renderdoc.org/builds

RenderDoc으로 분석할 수 있는 것

언리얼 서밋 2019에서 다룬 내용을 중심으로 정리해보려합니다.

영상에서는 언리얼 엔진에서 RenderDoc 플러그인을 설정하고 보여주고 있어서 언리얼 엔진의 렌더링 파이프라인에 맞춰 정리해보겠습니다.

위 파이프라인은 추상화한 내용으로 더 자세한 내용은 참고 자료 링크로 남겨두겠습니다.
쉬운 이해를 위해 추상화를 하면서 그림을 그리는 단계와 비교해서 쉽게 설명해주셨어요.

밑그림 - 밑그림 색칠 - 다듬기 - 그리기 - 마무리
각 단계별로 어떤 내용들을 볼 수 있는지 알 수 있었습니다.

⭐ 요약 ⭐

  • PrePass - BasePass - Lighting - Translucency 각 단계에서 일어나는 일을 분석할 수 있음
  • Event Browser 에서 각 단계의 이벤트를 확인하고 Texture Viewer, Mesh Viewer, Pixel History 등의 기능을 통해 분석, 프로파일링할 수 있다

PrePass - 밑그림

RenderDoc에서 렌더링 파이프라인에 따라 이벤트가 발생하고 그 시점에 따라 분석할 수 있게 되어있네요. (화면 왼쪽에 Event Browser에서 확인할 수 있음)

위에서 보고 있는 event는 PrePass(PrePass DDM_AllOpaque …)입니다.

이 단계에서는 하위 이벤트에서 각 에셋들의 메쉬들을 Mesh Viewer를 통해 확인하고 과도하게 메쉬를 복잡하게 만들지 않았는지를 확인할 수 있습니다.
(폴리곤을 과도하게 사용하지는 않았는지 = 너무 디테일하게 메쉬를 만들었는지)

BasePass - 밑그림 색칠

BasePass는 PrePass와 동일하게 모델을 화면에 맞게 변형합니다. 그 후에 PrePass과 대조해서 필요한 곳에만 색칠하는 작업을 반복합니다. PrePass를 이용하여 필요한 곳만 색칠할 수 있습니다.
이 단계에서는 Texture Viewer에서 각 에셋을 텍스쳐로 색칠하는데에 필요하지 않은 텍스쳐가 사용되거나 잘못된 경우를 찾아볼 수 있습니다.

영상 예시로는 범용 머터리얼을 사용해서 발생한 이슈로 필요한 텍스쳐만 사용하는 머터리얼로 수정하고 해결하는 것을 볼 수 있었습니다.

Lighting - 다듬기

Lighting 단계에서는 에셋들이 빛의 영향을 잘 받는지 비효율적으로 빛의 범위가 크게 설정되어있지는 않은지 확인할 수 있습니다.

라이팅 각 이벤트를 눌러보고 Texture Viewer의 Outputs를 보면 어떻게 라이트가 적용되어 렌더링 씬이 바뀌어가는지 알 수 있어요.


영상에서는 불필요한 큰 라이트 범위를 조정해서 라이팅 렌더링 비용을 개선했습니다. 👍

Translucency - 그리기

이 단계는 대략 그림이 완성되었으니 마지막 마무리로 계속 이미지를 겹쳐서 그리는 단계입니다.
이 때에 추가로 그리는 범위가 커질수록, 겹쳐서 그릴수록 어려워지게됩니다. (비용이 커짐)

이 부분에 대한 프로파일링, 최적화는 언리얼 엔진 에디터에서도 쿼드 오버드로(Quad Overdraw)나 셰이더 복잡도(Shader Complexity) 뷰를 통해서 보고 개선해볼 수 있습니다.

RenderDoc에는 Pixel History 기능을 통해서 픽셀이 어떻게 변화했는지 볼 수 있는 편리한 기능이 있습니다.

  1. Texture Viewer → Outputs → 이미지에서 확인하고자하는 픽셀 영역을 오른쪽 버튼을 누릅니다
  2. Outputs 하단에 History를 누릅니다 → 픽셀이 변화한 히스토리를 확인합니다

영상에서는 확인한 곳의 픽셀은 안개에 의해 색이 변해야하는 곳인데 변하지 않는 것을 픽셀 히스토리를 통해서 확인 → 개선!

PostProcess - 마무리

PostProcess 단계는 포토샵의 필터 적용과 같은 단계로 볼 수 있는데요. RenderDoc에서 언리얼 엔진의 PostProcess를 보기는 쉽지 않다고 합니다.
어떤 기능에 의해 합쳐진 효과들이 적용되고 보이게되어서 RenderDoc에서는 한계가 있다고 합니다.

나중에 엔지니어나 TA 분에게 물어보고 공부해보는 것으로 해야겠군요 😃

마무리

오랜만에 최적화 부분을 이것저것 들여다보니 재미있었네요. 😎
찾다보니 RenderDoc은 오픈소스로 알려져있는 툴이고 Nvidia나 Intel에서도 분석툴이 있어서 나중에 한번 슬쩍보는 것도 재미있겠다 싶습니다.
나중에 시간나는대로 Nvidia 부터 살펴보고 포스트해보겠습니다. 👋

가이드 문서, 자료

다른 그래픽스 분석 툴

Perforce(P4V) 체크아웃, 체크아웃 해제

체크아웃(Check Out), 체크아웃 해제(Check out file Revert)

Perforce Client(P4V) basics

체크아웃 방법

체크아웃 후 파일 오픈!
체크아웃 후 파일이 열린 모습
  • 체크아웃하려는 파일을 워크스페이스 파일 트리에서 파일을 선택, 오른쪽 버튼으로 체크아웃합니다.
  • Check Out, Check Out and Open 메뉴를 통해서 체크아웃할 수 있습니다.

체크아웃 참고

작업할 이미지 파일이 Lock된 상태"
이미 누군가 파일을 체크아웃했다고 합니다

  • 이미지, 에셋 등 Exclusive file을 체크아웃할 때 다른 작업자가 체크아웃하고 있을 경우 체크아웃할 수 없습니다.
  • 작업을 하고자할 경우 현재 진행중인 작업이 마무리되고 체크아웃하여 작업할 수 있습니다.

체크아웃 해제

파일 체크아웃 해제: Revert

  • 체크아웃한 파일들을 더 이상 수정하지 않는다면 Revert를 이용하여 체크아웃을 해제할 수 있습니다.
  • Changelist에서 마우스 오른쪽 버튼 -> Revert Files 또는 Revert Unchanged Files로 리버트할 수 있습니다.
    • Revert Files : Changelist에 있는 모든 파일의 수정을 취소합니다.(리버트합니다)
    • Revert Unchanged Files : Changelist에 있는 수정되지 않은 파일을 pending list를 제외합니다. (이것도 리버트라고 볼 수 있겠네요)
  • 파일 각각 선택하여 리버트할 수도 있습니다.

Revert시 변경한 내역이 있는 파일이 있는 경우

  • 다른 옵션 설정 없이 그냥 리버트해도 상관 없습니다.
  • 두번째 옵션(Get the latest revision and then check out all files that were reverted)의 경우 리버트 후 파일들을 최신 데이터로 업데이트한 뒤 체크아웃해줍니다.

다른 Perforce 가이드 문서들

Unreal Engine 크래시 분석 서비스 조사

조사 목적

  • 언리얼 엔진으로 게임을 만들 때에 사용하는 크래시 분석 서비스는 무엇이 있는지 알아봅니다.
  • 단순히 크래시 덤프를 수집하는 것에 그치지 않고 어떤 크래시가 많이 발생하고 있는지 트렌드나 특이점을 확인할 수 있는 서비스들이 있는지 찾아봅니다.

언리얼 크래시 리포터(Unreal Crash Reporter)

Unreal Crash reporter

언리얼 엔진 크래시 분석 서비스

알아본 크래시 분석 서비스

Sentry 👍

Sentry dashboard

https://sentry.io/welcome/
https://docs.sentry.io/platforms/unreal/

센트리(Sentry)는 웹 서비스, 앱 서비스에서도 많이 쓰는 이슈 관리 솔루션으로 알고 있습니다.
언리얼에서 사용하고자 할 경우에는 minidump를 직접 올리거나 크래시 리포터에 연결, 크래시 덤프를 올리는 방식인 것 같습니다.
가이드 문서를 보면 제한 사항이 있네요.

  • 20MB for a compressed request → 크래시 덤프 업로드시 압축된 데이터가 20MB 이하여야 하고
  • 100MB for the full crash report after decompression → 크래시 덤프 압축을 해제하면 100MB 이하여야 함

이런 제한을 참고해서 센트리를 도입해서 유의미하게 쓸 수 있는지 검토해야겠네요.
(덤프에 많은 정보를 남길 경우 센트리를 쓰지 못한다는 이야기… 😂)

플러그인이 있어서 설정은 쉬웠네요.
센트리 설정 경험기: Sentry - Uneal Engine 4.27 integration

BugSplat 👍

BugSplat dashboard

https://www.bugsplat.com/
https://docs.bugsplat.com/introduction/getting-started/integrations/game-development/unreal-engine

요 서비스는 언리얼 플러그인까지 있는 서비스여서 설정은 편할 것 같습니다.

센트리는 제한이 있었는데 BugSplat에도 제한 사항이… 있군요.
센트리랑 비슷하게 압축된 덤프의 사이즈가 20MB 여야합니다. 😂 (참고 링크)

  1. 에디터에서 프로젝트 설정에 “크래시 리포터 포함” & “디버그 파일 포함” 설정해주기
  2. DefaultEngine.ini 에 크래시를 보낼 주소를 입력해주기
    1. DataRouterUrl=”https://{database}.bugsplat.com/post/ue4/{appName}/{appVersion}”
  3. 4.26 이후 버전에는 DefaultEngine.ini 파일을 아래 경로에 복사해줘야 함(폴더가 없으면 다 만들어서 넣어줘야 함)
    1. 패키지 빌드 폴더\Engine\Restricted\NoRedist\Programs\CrashReportClient\Config
  4. 패키지 빌드에서 크래시 발생시키면 대시보드에서 바로 볼 수 있음

BugSplat도 Trial로 설정해보고 테스트해보았는데 가이드 문서대로 설정해볼 수 있었습니다.
BugSplat 설정 경험기: BugSplat - Uneal Engine 4.27 integration

Backtrace 👍

Dashboard

https://backtrace.io/
https://support.backtrace.io/hc/en-us/articles/360040106172-Unreal-Integration-Guide

백트레이스 서비스는 언리얼 엔진 설정이 가능한 솔루션이네요.
가이드 문서상 크래시 덤프 사이즈 제한은 보이지 않습니다.

요 친구도 플러그인이 있지는 않고 따로 크래시 리포터 설정에 DataRouterUrl 설정만 해주면되네요.
BugSplat과 동일하게 패키지 빌드 폴더\Engine\Restricted\NoRedist\Programs\CrashReportClient\Config 경로에 DefaultEngine.ini 가 있어야 크래시 덤프가 업로드되는 것 같습니다.

따로 플러그인은 있지 않고 단순 크래시 리포터 설정으로 가능하며 다른 크래시 분석 서비스와 비슷한 기능들을 가지고 있습니다.

  • Overview: 대시보드로 크래시 전체적인 현황을 볼 수 있는 뷰
  • Release: 업데이트된 버전 별로 크래시 지표를 볼 수 있는 뷰
  • Triage: 발생한 크래시를 테이블로 볼 수 있는 뷰. 필터를 적용해서 볼 수도 있음
  • Debug: 각 크래시별 정보를 상세히 볼 수 있는 뷰

크래시 정보를 상세히 볼 수 있도록 심볼 업로드는 프로젝트 세팅 > 심볼 설정에서 할 수 있습니다.

백트레이스도 크래시 분석 서비스들과 무난히 비슷한 서비스인 것 같네요.
실제 다른 서비스와 장단점을 상세 분석해보려면 다양한 케이스로 사용해봐야할 것 같습니다.

Raygun 🤔

(⚠ 언리얼 엔진에 설정하기 쉽지 않은 서비스)

https://raygun.com/

레이건 서비스는 따로 언리얼 엔진 플러그인이 있지는 않네요.
이 서비스를 사용한다면 C++ 항목으로 구성하고 minidump(breakpad)를 업로드하는 방식으로 시도해보았는데 잘 되지 않았습니다.

  1. 가이드 문서 확인 → sender.SendCrashReport(L"https://api.raygun.com/entries/breakpad?apikey=...", userCustomData, files, 0); 코드 확인 → URL로 덤프를 보낼 수 있도록 설정
  2. DefaultEngine.ini 에서 [CrashReportClient], DataRouterUrl 항목에 위 URL 입력
  3. 크래시 발생 후 크래시가 남는지 확인 → 확인할 수 없었음

다른 서비스에서 했던 것 처럼 크래시 업로드 URL에만 덤프를 올리면 가능할 것으로 기대했지만 잘되지 않네요.
Raygun은 웹서비스 설정이 더 편한 서비스라고 보여서 설정을 더 시도해보지는 않았습니다.

Countly ❓

(⚠ 언리얼 엔진에 설정하기 쉽지 않은 서비스)

https://countly.com/
https://countly.com/feature/crashes-errors

카운틀리는 자체 서버 구축과 클라우드 서비스를 사용할 수 있는 서비스 시스템으로 볼 수 있습니다.
자체 서버 구축: https://support.count.ly/hc/en-us/articles/360036862332-Installing-Countly-server
언리얼 엔진 크래시 분석 서비스로 사용하려면 자체 서버 구축과 클라이언트에 minidump로 업로드 설정하는 방법으로 가능하네요.

마무리

위와 같이 언리얼 엔진 게임으로 크래시 현황, 분석을 할 수 있는 5가지 정도의 서비스를 알아보았습니다.

핵심 기능은 비슷한 것 같았고 2가지 정도는 C++ 빌드로 만들어진 프로그램을 minidump를 업로드하고 그 것을 분석하는 방식을 가지고 있었네요.
대부분 앱과 웹 서비스에서 발생하는 비정상 종료, 크래시를 분석하는 데에 맞춰져있었습니다.

언리얼 엔진으로 접근성이 좋았던 것은 Sentry 정도였고 나머지는 프로젝트 설정에 따라 커스텀 설정을 해줘야하는 것들이 좀 있었습니다.

Countly의 경우에는 서버를 자체 구축할 수 있다는 점에서 크래시 덤프 파일 사이즈가 크더라도 사용할 수 있겠다 싶었습니다.
(덤프에 많은 정보를 담고자할 경우 덤프 파일이 100MB가 넘어가는 경우도 있긴하더라구요.)

Countly 설정은 클라, 크래시 분석 서비스 서버 설정까지 해야해서 나중에 한번 해보고 포스트 남겨보겠습니다. 👋