오늘은 최적화 관련된 기술적인 이야기
= 내가 기반지식이 좆도 없어서 번역이 부정확할 수 있음
https://www.factorio.com/blog/post/fff-415
FFF #415 - 수정, 개선, 최적화
게시자 Rseding
2024-06-14
안녕하세요,
2.0 개발 기간 동안 새로운 기능과 삶의 질 향상에 많은 시간을 할애했지만, 여전히 작은 세부 사항과 기술적인 개선에도 신경을 쓰고 있습니다.
결정론적인(deterministic) 멀티스레딩은 어렵습니다
최근 모딩 API와 여러 대의 Windows 및 Linux 컴퓨터를 사용중인 플레이어와 관련된 비동기화 버그가 신고되었습니다. 처음에는 모드 개발자가 뭔가 실수했다고 생각하고 무시하고 싶었지만, 수년 동안 버그 신고를 충분히 봐왔기 때문에 조사도 하지 않고 무시하는 것은 나쁜 생각이며 명백한 잘못이라는 것을 알고 있습니다.
저는 비동기화를 재현할 수 없었지만 해당 플레이어는 쉽게 재현할 수 있었습니다. 처음에는 Windows와 Linux 간의 문제라고 생각했지만(이런 문제가 많이 발생했거든요), 플레이어는 두 컴퓨터 모두에서 Linux를 세팅하고도 버그를 재현할 수 있었습니다. 그 다음에는 하드웨어 문제라고 생각했습니다. 제대로 작동하지 않는 문제가 있는 컴퓨터를 많이 보았기 때문입니다. 하드웨어가 고장났다고 설득하는 것은 최상의 시나리오에서도 어렵고 시간이 많이 걸리는 일입니다.
제 컴퓨터 한 대에서 문제를 재현하려고 여러 번 시도했지만 실패한 후, Boskid는 여러 대의 컴퓨터를 사용하여 문제를 재현하는 데 성공했습니다. 로컬에서 버그를 재현할 수 있다는 것은 보고된 버그를 수정하는 데 소요되는 시간의 약 90~95%를 차지한다고 생각합니다. Boskid는 필요에 따라 문제를 재현하면서 컴퓨터의 CPU 코어 수가 다르다는 사실로 문제를 좁힐 수 있었습니다. 새로 알게 된 지식을 바탕으로 그는 제 컴퓨터 한 대에서 실행할 수 있는 테스트를 만들어 인위적으로 CPU 코어 수가 적은 것처럼 꾸며서 비동기화 버그를 재현할 수 있었습니다.
결국 이 문제는 2017년 7월 22일에 추가한 이래로 게임에 존재해 온 결정론적 멀티스레딩 문제를 드러내기 위해 4개의 서로 다른 단서가 모두 합쳐져야 했습니다.
- 모드는 청크 생성 이벤트를 수신하고 청크가 생성되면 청크의 타일을 변경해야 합니다.
- 여러 개의 청크 생성을 요청하려면 모드가 필요합니다.
- 요청된 모든 청크가 지금 바로 생성되도록 강제하는 모드가 필요합니다.
- 이 게임은 CPU 코어 수가 다른 두 대의 컴퓨터에서 실행해야 했습니다.
- 청크를 '지금 바로' 생성하는 로직은 사용 가능한 모든 CPU 코어를 사용하려고 시도하지만, 코어 수가 다른 조각과 결합되면 청크 생성 결과가 약간 달라지는 방식으로 수행되었습니다.
이 수정 사항은 구현하기가 그리 복잡하지 않았고 2.0에 포함될 예정이지만, 멀티스레딩이 어렵고 결정론적 멀티스레딩은 더욱 어렵다는 것을 잘 보여줍니다.
멀티플레이어 게임 자동 일시정지
데디케이티드 서버에는 마지막 플레이어가 연결을 끊으면 서버가 자동으로 일시정지되는 기능이 있습니다. 이 기능은 훌륭하게 작동하며, 플레이어가 자리를 비웠을 때 바이터들이 기지를 먹어버릴 걱정 없이 데디케이티드 서버를 켜둘 수 있습니다. 단, 지금까지 처리하지 못한 몇 가지 특이한 경우가 있습니다.
사례 1: 자동 일시 중지된 서버에 접속하면 게임이 완전히 로딩되지 않았더라도 즉시 플레이가 재개됩니다. 이 문제는 수년 동안 어떤 이유에서인지 방치되었지만, 해결은 매우 간단했습니다. 2.0에서는 자동으로 일시중지된 서버는 최소 1명의 플레이어가 게임에 완전히 로딩될 때까지 일시중지된 상태로 유지됩니다.
사례 2: 참가하는 플레이어가 진행 중인 게임을 따라잡아야 하는 경우. 이 방법은 "일반적인" 게임에서는 잘 작동하며 기존 플레이어가 참가하는 플레이어를 기다릴 필요 없이 게임을 계속할 수 있습니다. 하지만 맵이 너무 크거나 인터넷 연결이 느린 경우에는 플레이어가 문제를 겪을 수 있습니다. 참여하는 플레이어 없이 게임을 계속 진행하면 서버를 완전히 다운로드하고 로드하고 따라잡는 데 1분, 2분 또는 몇 분이 걸릴 수 있습니다. 2.0에서는 '플레이어가 참여할 때 자동 일시 중지' 옵션을 추가했으며, 이 옵션은 이름 그대로 작동합니다.
더 빠른 건설 로봇 작업
1~2주 마다 누군가 "왜 내 건설 로봇이 작동하지 않나요?"라고 질문하고, 그들이 제공하는 스크린샷에는 "600개의 작업에 재료/로봇이 누락됨"이라는 작은 경고가 표시되어 있는 것 같습니다. 이 문제는 로봇이 개발된 이래로 계속되어 왔으며, 오늘날에도 여전히 좋은 해결책을 찾지 못하고 있습니다.
문제는 로봇이 수행해야 하는 작업이 주어지면 게임에서 해당 작업을 수행할 수 있는 범위 내에 있는 물류 네트워크에서 가장 적합한 로봇을 찾아야 한다는 것입니다. "이 물류 네트워크가 엔티티의 범위 내에 있는가"에 대한 검사는 O(Roboport-Count)입니다. 플레이어가 로보포트 1개를 만들든, 10만 개를 만들든, 컴퓨터가 감당할 수 있는 만큼 만들 수 있기 때문에 속도가 얼마나 느려질지는 우리가 제어할 수 없습니다. 따라서 게임이 실행되는 동안 작업이 중단되지 않도록 해야 합니다. 이를 위해 매 틱마다 몇 개의 건설 로봇 작업만 처리합니다.
1.1에서는 게임이 업데이트될 때마다 건설 작업을 3번 확인합니다. 로봇을 찾지 못하면 현재 업데이트가 중지됩니다. 실패한 시도에 대한 알림은 10초 동안 지속됩니다. 따라서 초당 60회의 업데이트와 알림당 10초를 적용하면 첫 번째 알림이 종료되기 전까지 600개의 알림이 생성된다는 뜻입니다. 이것이 바로 "600개의 작업에서 재료/로봇이 누락됨"이라는 마법의 알림 문구의 정체입니다.
제가 팩토리오에서 일한 이래로 이런 방식으로 작동해왔고 앞으로도 기본적인 수준에서 이런 방식으로 작동할 것입니다. 플레이어가 더 많은 로보포트를 만들수록 작업 속도가 느려질 수 있다는 것을 알기 때문에 업데이트할 때마다 작업 확인 횟수를 늘릴 수는 없습니다.
올해 초에 누군가(포럼 게시물)가 이 문제를 다시 발견했지만, 저희가 할 수 없다고 말한 것을 직접 '해결'하기로 결정했습니다: "업데이트당 확인된 작업 수를 업데이트당 1개에서 374개로 늘림". 또한 36,815개의 로보포트를 구축했습니다. 예상대로 게임은 무척 느렸습니다.
하지만 느린 부분을 훨씬 더 빠르게 만들 수 있다면 어떨까 하는 생각이 들었습니다. 알고리즘을 더 빠르게 변경하는 것처럼요? 게임에서 로보포트 물류 및 건설 영역을 취하고 그 결과 사각형 합을 계산하는 일련의 로직이 이미 있다는 것을 기억했을 때 영감이 떠올랐죠. 간단히 말해서 모든 로보포트의 전체 면적을 커버하는 멋진 중복 제거 직사각형 세트를 생성하는 것입니다. 이를 렌더링에 사용하여 로보포트가 서로 가까이 있을 때 지나치게 많이 그려지는 것을 방지합니다.
결과적으로 직사각형을 정렬하는 작업과 함께 간단한 이진 검색을 수행하여 주어진 작업이 네트워크 영역 내에 있는지 확인할 수 있었습니다. 결국 36,815개의 로보포트에서 O(N), 900~직사각형 결합 영역에서 O(N), 900~직사각형 결합 영역에서 O(logN)으로 확인했습니다.
"이 네트워크에 있는지"를 확인하는 데 드는 시간이 비용이 많이 들던 것에서 본질적으로 무료로 바뀌었습니다. 이 속도 향상으로 작업 확인 속도를 2.0에서는 꽤 끌어올릴 수 있었고 이 문제를 해결할 수 있을 것으로 기대합니다.
언제나 그렇듯, 평소와 같은 장소에서 여러분의 생각을 보고하세요.
오잉 행성 얘기 끝?
좀 텀좀 두고 풀겠지
몽말인지 모르겠지만 600개에서 늘어난다는얘기지?
대충 봤을 때, 로보포트가 너무 많아지면 작업 요청이 로봇네트워크영역에 속하는지 계산하는 시간이 게임을 멈추게 할 정도로 오래걸릴 수 있어서 임의로 제한을 둬서 작업이 네트워크 안에 있음에도 불구하고 600개짜리 그 알림이 떴던건데 이번에 계산하는 알고리즘을 바꿔서 계산시간을 획기적으로 줄이고 그 알림이 더이상 안뜨게 한다는 의미인듯??
이제 로봇이 건설 바로바로할듯? - dc App
오른쪽 밑에 N개의 건물 건설재료가 없음 이라고 뜨는게 한번 확인할때 3번 확인하고 알림을 10초간 띄우는데 확인하는게 화면 업데이트 할 때마다 하니까 60프레임이면 초당 60번을 확인함. 이걸 곱하면 1개 건물이 건설재료가 없다면 10초 뒤에는 60번확인 x 10초띄움 에 의해서 600개의 건설재료가 없다고 뜨는 문제가 있었는데 그걸 해결한다고 하는거일듯
와 정말 무슨 말인지 하나도 모르겠어
로보 포트 문제는 그럼 크라2 고급 로보 포트 처럼 범위를 늘리는 로보포트를 쓰는 식으로 평상시 활성화 되어 있는 로보포트 수를 줄여주면 저런현상을 줄일수 있다는 뜻인가? 평상시에 내기지를 100개의 로보 포트로 커버 했다면 고급 로보 포트는 16개로 커버가 되니깐..
물류네트워크를 잇기 위해서는 건설네트워크가 필연적으로 겹치게 되고, 봇다이소 같은곳에는 로보포트를 여러개 붙여서 건설하는데 이게 성능하락의 원인이 된다고 함. 그래서 2.0에서는 로보포트 0부터 n까지 확인하는거에서 로보포트가 연결된 범위는 1개로 치고 확인하는거임. 마치 작은종이를 붙여서 큰 작품을 만드는것보다 큰 종이를 잘라내서 큰 작품을 만드는게 빠른것처럼
내맞워요
대충 블프도배하면 천지사방에 경고뜨면서 숫자 이상하게 움직이던거 수정했다는거...맞겠지?? - dc App
ㅇㅇ 오른쪽 밑에 N개의 건물 건설재료가 없음 이라고 뜨는게 한번 확인할때 3번 확인하고 알림을 10초간 띄우는데 확인하는게 화면 업데이트 할 때마다 하니까 60프레임이면 초당 60번을 확인함. 이걸 곱하면 1개 건물이 건설재료가 없다면 10초 뒤에는 60번확인 x 10초띄움 에 의해서 600개의 건설재료가 없다고 뜨는 문제가 있었는데 그걸 해결한다고 하는거일듯
마지막 시복도 이야기가 살짝 이상하게 번역됐네 기존 3만여개의 로보포트를 일일히 검사하던 것에서 900개 가량의 직사각형 형태를 하나씩 점검하는 수준으로 최적화를 한 번 하고, 그 다음으로 한 번 더 최적화를 해서 900개를 일일히 검사하지 않고 log 900 번만큼만 검사를 하게끔 해줬다는거임 로보포트 도배했을때 렉이 존나 줄었다고 이해하면 됨
그치 건설구역 늘린다고 무지성으로 마름모모양 로보포트 도배나 그리드에 로보포트 넣어서 무지성 복붙할때 최적화가 잘 되니까 성능향상에 존나 도움이 될듯
잉 볼만한게 로봇뿐이네
콘크리트 5백만개정도 로봇으로 깔면 몇시간씩 걸리던거 이제 고쳐질려나. 멀티플레이어 자동정지기능은 진짜 사람 몇명 없는 대형모드서버에서나 쓸듯.. 저장할때 툭툭끊기는것도 짜증나는데 사람 들어올때마다 끊기면 와우..
다음주에 큰거오냐??
팩개발자 위에 날아다니는 '해당 플레이어'ㄷㄷ - dc App
멀티쓰레딩을 제대로 만드려면 10년차 개발자는 되어야 한다는 유튜버 있던데 맞말인듯 - dc App
600개가 뜨는걸 개선한다는건 역으로, 더 많은 숫자가 떠야 하는데 600밖에 안뜨던걸 개선한다는거임
존나 넓은 범위에 콘크리트 바르라는 명령 내려보면 알겠지만, 재료확인하고 일할 수 있는지 체크 (추측이지만 실제로 일하라는 명령 내리는것까지)가 왼쪽 위부터 오른쪽 아래로 한줄씩 읽어오면서 갱신함
그래서 문제가 여럿 있는데 경고가 600개만 떠서 실제로는 3만개가 필요한데도 600개만 부족한것처럼 표시되고 (당연 실제로는 3만개 찍어야 하니 600개 찍어봐야 해소안됨), 덤으로 그 업무큐가 너무 많아서 다른 재료있는 건설명령도 갱신틱 안와서 로봇이 멀뚱멀뚱 놀기도 했음
그렇다고 로봇 일하는 명령 갱신을 더 자주 시키면 게임 성능이 유의미하게 떨어지니까 알고리즘 개선을 했단 뜻임
1~2주 마다 누군가 "왜 내 건설 로봇이 작동하지 않나요?"라고 질문하고, 그들이 제공하는 스크린샷에는 "600개의 작업에 재료/로봇이 누락됨"이라는 작은 경고가 표시되어 있는 것 같습니다. 이 문제는 로봇이 개발된 이래로 계속되어 왔으며, 오늘날에도 여전히 좋은 해결책을 찾지 못하고 있습니다.
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
저거 아이디어로 최적화 시킨거 대단하네 - dc App