이 글은 내 자신에 대해서 반성하는 글이다.

 

과거에 프로그래밍 관련 번역에 대한 불만들 토로하는 글을 쓴 적이 있다(프로그래밍 관련 번역에 대한 사설). 번역된 단어에 제대로 된 뜻이 담기지 않았다는 불만이었다.

 

나는 최근 며칠 간 유니티 5.6의 AssetBundle 초안 문서를 번역하는 작업을 했었다. 거기에 등장하는 용어 중에 배리언트(Variants, 변형)이라는 단어가 있는데, 유니티의 에셋 번들에서는 에셋 번들 배리언트로 하나의 오브젝트에 대해서 에셋 번들을 만들 때 사용하고자 하는 방식이나 버전에 따라서 에셋 번들을 다르게 만드는 것을 의미하는 것이었다.

 

예를 들어 하나의 오브젝트가 있는데 이것이 작동하는 방식이 iOS와 안드로이드가 달라서 에셋 번들을 다르게 빌드해야한다던지, 두 장의 텍스쳐를 하나는 고해상도 배리언트로 묶고 하나는 저해상도 배리언트로 묶는다던지 하는 방식으로 사용하는 것이다.

 

하지만 나는 이 단어의 의미나 용도에 대해서 깊게 고민하지 않았고 그 뜻이 명확하게 드러나 보이지 않는, 단순한 사전의 뜻 그대로 "변형"이라는 단어를 사용해서 번역하는 실수를 저지르고 말았다.

 

Direct3D에서 사용되는 서피스라는 단어의 표면적인 뜻에서 진짜 뜻을 찾아 헤매던 것을 고생을 잊은 것이다.

 

번역 작업을 할 때는 기계적으로 번역하지 말자.

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

 

나는 과거에 같은 학교를 다니는 후배들에게 프로그래밍 멘토링을 진행한 적이 있다. 물론 지금도 그렇게는 뛰어나지 않고 그 당시에도 뛰어나지 않은게 내 프로그래밍 실력이었지만 적어도 막 입문한 친구들에게 가르쳐줄 정도는 되었던 것 같다.

 

뭐, 중요한 점은 그 부분은 아니고, 내가 그때 가르쳤던 친구들이나 혹은 내 주변 사람들이 가르치던 사람들이 공통적으로 하던 이야기가 있는데, 그것은 바로 "머리 속으로는 어떻게 만들어야 할지 알겠는데, 막상 코드로 옮기려고 하니 너무 어렵다." 라는 것이었다. 물론 이런 이야기 없이 그냥 쭉쭉 잘해 나가던 친구들도 있었다. 자랑은 아니지만 나 역시 저런 생각을 해본 적이 없는 편에 속해서, "아니 이게 무슨 말인가?" 싶었다. 어떻게 만들어야 할지 알았으면, 그냥 코드로 만들면 되는거지, 왜 코드로 옮기려고 하면 그게 안된다는 것인지 그 당시에는 도무지 이해가 되지 않았다.

 

하지만 내가 프로그래밍을 공부한 과정을 곰곰히 되새겨본 결과, 프로그래밍을 배우기 시작한 지 얼마 되지 않았을 때의 나 역시 같은 문제에 부딪힌 적이 있다는 것을 깨달을 수 있었다. 그것을 깨닫고 난 이후에 내가 다시 생각하게 된 것은 "머리 속으로는 어떻게 만들어야 할지 알겠는데, 막상 코드로 옮기려고 하니 너무 어렵다."라는 문제에는 누구나 부딪히게 된다는 것이고, 진짜로 그 시점에서 중요한 문제는 "코드로 옮기려고 하니 어렵다."가 얼마나 어려우냐보다 "그 상태에서 얼마나 빨리 벗어나느냐"라는 것이다.

 

누군가는 "머리 속으로는 어떻게 만들어야 할지 알겠는데, 막상 코드로 옮기려고 하니 너무 어렵다." 라는 말을 일주일 정도 하더니 더 이상 그런 말을 하지 않고 프로그래밍을 하게 되고, 누군가는 그 말을 1년도 더 넘게 하고 있다면, 그 차이는 무엇에 있는 것일까?

 

난 그 차이가 숙달과 경험, 그리고 연습량에 달려있다고 본다.

 

간단한 예를 들자면, 한 번도 요리를 해본 적도 없는 사람에게 마파두부를 만들고 시켰다고 해보자. 그 사람의 머리 속에는 자신이 평소에 먹던 마파두부가 떠오를 것이다. 하지만 막상 요리를 진행하면 그 사람은 무엇부터 해야하는지 모르고 우왕좌왕하게 될 것이다.

 

그러면 그 다음엔 요리를 해본적 없는 사람에게 마파두부를 만드는 법을 알려주고 만들라고 시켜보자. 과연 그 사람은 완벽하게 마파두부를 만들어낼 확률이 높을까? 아니다. 분명 상당한 시간이 걸리고도 제대로 된 결과물을 만들어 내지 못할 확률이 높을 것이다. 칼질은 서투르고, 재료도 볶다가 태울지도 모른다. 그리고 레시피를 이미 알고 있지만, 그것을 제대로 따라하지 못하고 버벅대는 경우가 많을 것이다. 그렇다면 이 사람이 마파두부를 잘 만들기 위해서는 어떻게 해야 할까? 답은 하나 뿐이다. 마파두부를 계속 만들어 보는것.

 

나는 프로그래밍도 이것과 마찬가지라고 생각한다. 머리 속에 만들어진 논리를 코드로 바꾸는 능력을 많은 프로그래밍을 통해 숙달시키는것과 머리 속에 들어있는 마파두부 만드는 법을 많은 연습을 통해 익히는 것. 무엇이 다른가?

 

앞서서 나는 이 과정을 상당히 빨리 벗어났다고 이야기 했었다. 나는 한때 내 꿈이 무엇인지를 놓고 방황하다가 24의 나이가 되어서야 프로그래밍에 입문했다. 게임을 만들기 위해서. 그리고 내가 게임 프로그래밍을 배울 수 있는 학교에 왔을 때, 내 주변의 친구들은 아직 20살이었고, 군대를 다녀온 시간 2년을 그 친구들보다 앞서있다고 생각해도 2년은 뒤쳐져서 시작하는 것이었다. 그러니 당연히 이렇게 생각할 수 밖에 없었다. 남들보다 더 많이 코딩을 하자. 분명 이 프로그래밍 책의 뒤에 예제의 해답이 있는 건 알지만, 나만의 답, 내가 해결하기 전에는 보지 말자. 책의 해답이 더 나은 것이라면 익히고, 내 답이 더 나은 것이라면 뿌듯함을 느끼면 된다. 그렇게 공부를 하니 남들이 "코드로 옮기는 것이 어렵다"는 말에 공감하기 어려워질 정도로 그 단계를 빨리 지나가 버렸다.

 

연습량이 적은 데에는 3가지 이유가 있을 수 있다.

 

1. 정말 게을러서.

2. 너무 완벽을 추구해서.

3. 겁이 많아서.

 

1번은 절실함을 느끼지 않는 한 답이 없다.

 

2번은 완벽한 코드를 만들어 내야한다는 압박감에 시달려서, 혹은 코드가 작동하는 원리의 깊은 곳까지 알고싶어서, 코드를 이리 뒤지고 저리 뒤지다 한 세월이 걸려서 연습하는 속도도 느려지고 연습량이 적어진다. 물론 이것은 좋은 자세임에는 틀림이 없다. 하지만 지금의 문제를 느끼는 단계라면 너무 과한 태도라고 생각된다. 지금의 단계는 분명 빨리 지나가도 되는 단계일 것이다. 지금 이 단계를 넘어가면 깊이를 알 수 없고 드넓은 바다가 있는데 작은 물웅덩이 속에서 웅덩이 속을 떠다니는 모래 알갱이를 세고 있는 꼴이다. 지금 단계가 그렇게까지 완벽하게 파야되는 단계인지 그렇게까지 완전해야 하는 단계인지 잘 생각해보라.

 

3번이 가장 일반적으로 많은 케이스라고 생각된다. 코드를 치기 전에도 버그가 나면 어떻게 하지? 하고 시작조차 못하는 혹은 코드 한줄한줄마다 이게 틀렸으면 어떻게 하지? 하는 부류이다. 내 친구의 프로그래밍 과외를 받는 어떤 사람은 그랬다. "이런 것을 만들어보라"고 시키면 마우스를 이리저리 움직여보다 코드 한 줄을 겨우 치고는 묻는 것이다. "이렇게 하는게 맞나요?"하고. 그리고 그 질문은 한줄한줄 계속 된다.

 

나는 이런 겁 많은 사람들에게 일단 버그가 있든 없든 알 수 없지만 신텍스 에러(Syntax error, 문법 오류)만 없게 주어진 문제를 완성하라고 말하고 싶다. 그리고 컴파일해보면 알게 될 것이다. 버그가 있는지 없는지. 만약 버그가 있다면 버그를 수정하면 되는 것이고 없다면 좋은 것이다. 물론 처음부터 버그가 없게 설계를 한다면 좋겠지만 아무리 좋은 설계라고 해도 버그가 아예 없을 확률은 낮으니, 완성해서 컴파일 해보는 것이 중요한 것이다. 그래야 당신은 프로그래밍 연습을 한 것이고, 공부를 한 것이다.

 

그러니 연습을 해라. 코딩을 해라. 프로그래밍을 해라.

 

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

프로그래밍을 할 때 있어서 모든 일이 처음 설계한대로 흘러간다면 얼마나 좋을까? 하지만 Hello World를 출럭하는 프로그램이 아닌 이상에야 그런 일은 있을 수 없다.

 

확장성을 위해, 재사용성을 위해, 더 나은 구조를 위해 코드와 설계는 변하기 마련이다. 그 와중에 많은 함수나 변수, 클래스가 추가되고 삭제된다. 물론 혼자서만 하는 작업이라면 코드를 바꾸고 바꾼 코드를 바로 적용하면 되지만, 코드 베이스를 만드는 사람과 그 베이스를 이용해서 작업하는 사람이 따로 있는 상황이라면 이야기가 조금 달라진다.

 

만약 베이스를 작업하는 사람이 몇몇의 함수를 삭제하고 다른 이름의 함수로 대체했다면 그 베이스를 응용하는 사람 역시 그에 대한 사실을 알아야 한다. 물론 일반적인 상식으로 베이스 작업자가 베이스를 변경했다면 다른 작업자에게 바로 알려주고 다른 작업자는 바로 변경하는게 맞는 이야기지만, 사람과 사람 사이의 의사소통이라는게 말처럼 쉽기만 하던가. 베이스 작업자가 변경사항을 몇 개는 빠뜨리고 알려줄 수도 있고, 다른 작업자는 이야기를 들었지만 까먹을 수도 있는 일이다. 여튼 의사소통 과정에서 문제가 발생했다면 다른 작업자는 뜬금없이 바뀐 베이스 코드에 당황을 금치 못할 것이다.

 

그런 상황을 맞이한 다른 작업자는 당연히 문제를 해결하기 위해서 베이스 작업자에게 어떻게 변경된 것인지 물어보던지, 코드를 뒤져서 바뀐 함수를 적용하던지 하는 노력을 하겠지만 아무래도 이런 방식은 해결 속도도 느릴 뿐더러 효율적이지 못하다.

 

그렇기 때문에 나온 해결책이 바로 [Obsolete] 라는 어트리뷰트이다.

 

class TestClass
{
    [Obsolete]
    public void Function1()
    {
    }
}

 

더 이상 사용하지 않거나 그럴 예정인 클래스나 함수, 변수의 앞에 [Obsolete] 어트리뷰트를 붙여주면 된다. 그렇게 하면 해당 함수를 호출할 때 초록색 밑줄과 함께 더 이상 사용하지 않는 함수라는 경고가 뜬다.

 

 

그리고 툴팁에서는 함수 앞에 [deprecated]가 붙게 된다.

 

이 [Obsolete]는 세 가지 방식의 오버로딩을 지원한다.

 

class TestClass
{

    [Obsolete]
    public void Function1()
    {

    }

    [Obsolete("Not use anymore.")]
    public void Function2()
    {

    }

    [Obsolete("Not use anymore.", true)]
    public void Function3()
    {

    }
}

 

[Obsolete] :: 더 이상 사용하지 않는 코드라는 경고만 출력한다.

 

[Obsolete(string message)] :: 더 이상 사용하지 않는다는 경고에 추가적인 메시지를 남길 수 있다. 이 메시지를 통해 더 이상 사용하지 않는 코드 대신에 사용할 코드를 사용자에게 알릴 수 있다.

 

[Obsolete(string message, bool error)] :: 추가적인 로그와 함께 이 코드를 사용할 경우에 컴파일 에러를 띄울지를 결정한다. true를 넣어주면 컴파일 에러를 띄워서 이 코드를 사용하면 컴파일을 할 수 없게 된다.

 

 

이런 식으로 [Obsolete]를 적절하게 사용하면 베이스 작업자는 코드 작업만으로 다른 작업자에게 코드가 변경되었음을 알림과 동시에 그에 대한 해결책도 전해줄 수 있다. 베이스 작업자가 코드를 변경하고 다른 작업자에게 변경사항을 일일이 알리는 것보다 훨씬 빠르고 효율적인 해결책이다.

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

효과적으로 Debug를 하기 위해서는 Debug 빌드를 유지해야한다.

 

하지만 사람들은 Debug 빌드를 잘 사용하지 않는데 그것은 Debug 빌드의 속도가 Release 빌드에 비해서 컴파일 시간도 실행 시간도 느리기 때문이다.

 

Debug 빌드는 기본적으로 최적화 기능이 꺼져있기도 하고, 프로그래머가 에러를 찾기위해 온갖 assert를 넣고 하다보면 프로그램이 더욱 느려지기 마련이다.

 

하지만 Release 빌드는 속도가 빠른 반면에 에러를 잡기위한 디버깅이 힘들어진다. 최적화 단계에 들어선 이후에는 성능이 매우 중요하겠지만 그 이전 단계에서는 프로그램이 얼마나 올바르게 동작하는 가가 제일 중요하다. 그렇기 때문에 버그를 빠르게 찾아내고 수정하기 위해서는 반드시 Debug 빌드를 언제나 컴파일되고 실행되게 유지해야한다.

 

만약 Debug 빌드가 컴파일되지 않게 망가뜨린 프로그래머가 있다면 그는 반드시 다른 프로그래머가 언제든지 Debug 빌드를 실행시킬 수 있도록 복구시켜 두어야 한다.

 

Debug 빌드를 사람들이 잘 쓰지 않는 이유는 속도가 느리기 때문인데 속도를 빠르게 하기 위해 무조건 Release 빌드는 쓰는 것이 아니라 어떻게 해서든 Debug 빌드를 빠르게 만들어야 한다.

 

Debug 기능을 쓸 수 있지만 어느 정도 최적화 기능을 켠 Fast Debug 빌드를 만든다던가. 각 부서별로 자기 부서에 필요한 부분만 Debug로 돌리고 나머지는 Release로 돌릴 수 있게 자동화를 한다던가. 여기저기 있는 assert를 효과적으로 제거한다던가하는 방식으로 말이다.

 

참고 ::

 

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

 

 

반응형

버그로 인한 메모리 오염, 즉 예상되지 않은 메모리 값 변경, 참조 등에 의해서 발생한다.

 

원인을 다양한데 대부분 안전하지 않은 함수의 사용, 잘못된 함수 사용, 잘못된 포인터 사용 등 프로그래밍 실수로 인해서 발생한다.

 

실수로 사용중인 메모리를 다른 엉뚱한 곳에서 메모리를 덮어쓴다거나 들어가지 말아야할 메모리 주소에 데이터가 들어가는 것을 의미한다.

 

 Memory corruption이 발생했을때 이 메모리에 잘못된 값이 쓰여졌다는 것은 바로 알 수 있지만 이 잘못된 값이 어디서 온 것인지 알기가 쉽지 않다.

 

왜냐하면 사용중인 메모리에 다른 값이 쓰여졌을 당시에는 문제가 발생하지 않고 이후에 덮어씌워진 메모리를 다시 사용할 때가 되어서야 에러가 발생하기 때문이다.

 

만약에 운이 나쁘다면 디버그 중에는 그 잘못 쓰여진 메모리를 다시 사용하는 일이 발생하지 않다가 프로그램을 릴리즈하고 출시한 이후에 실제 버그가 발생하는 경우가 있을 수 있다.

 

그렇게 되면 구매자는 언제 터질지 모르는 시한폭탄같은 프로그램을 구매하게 된 것이고 곧바로 화를 내며 환불을 요구하게 될 것이다.

 

출시한 이 후에야 버그 리포트를 받은 프로그래머 역시 멘탈이 무너질 것이 분명하고... 이 문제를 해결하는 것은 매우 힘들 것이다.

 

그리고 멀티 쓰레딩을 하면서 여러 쓰레드에 한 메모리에 접근하는 상황이면 더욱 복잡하다.

 

포인터를 잘못 다뤄서 이런 문제가 발생하는 경우가 많기 때문에 항상 포인터를 다룰 때는 조심해야 한다.

 

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

요즘 칩에는 벡터 레지스터라는 개념으로 메모리를 배치하는데, 이 벡터 레지스터 하나에 정수형이나 실수형 4개를 한꺼번에 담아둘 수 있다고 한다.

 

loop 작업시 float이나 int 형식의 4바이트 변수의 배열에 대해 하나씩 훑으며 작업할 때 굳이 하나씩 작업하지 않고 4개를 묶어서 16바이트를 벡터 형식으로 한 번에 처리할 수 있고 이것은 물론 스칼라 형식으로 하나씩 작업하는 것보다 빠르다(이론 상 최대 4배까지 빠를 수 있다).

 

이런 것을 Vectorization이라고 한다. 일반적으로 최신 컴파일러는 이런 Vectorization을 자동으로 수행해준다.

 

어떤 조건하에선 수행하지 못하는 경우가 있다. 수백만줄의 코드를 모두 체크하지는 못하기 때문에 이 체크에 실패하면 Auto Vectorization에 실패한다.

 

Auto Vectorization에 실패했을때 알아내는 방법은 프로그래머는 어셈블리어 코드를 확인하는 방법 밖에 없는데 이것은 어려운 일이다

그리고 Debug 빌드에서는 최종 코드를 내는 것이 아니기 때문에 최적화 기능의 상당부분이 꺼져있어서 Vectorization 또한 수행되지 않는다.

 

10000개 짜리 float 배열 두 개에 대한 loop 작업을 10000회를 수행했을 때의 결과물이다.

 

Release : x64

역으로 성능이 감소하는 케이스가 발생하기는 하지만 대부분 1%이하의 확률이다.

평균적으로 40~50%의 성능 향상을 기대할 수 있다.

 

Release : x86

x64 버전과 거의 비슷한 수준의 결과물을 얻을 수 있다.

반복적으로 실험한 결과 평균 성능 향상 비율을 2~10% 가량 떨어진다.

 

Debug

Debug 빌드에서는 최적화 기능이 꺼져있기 때문에 성능 향상이 거의 없음을 알 수 있다.

 

 

Vectorization 성능 비교 코드

#include <iostream>
#include <string>
#include <Windows.h>
using namespace std;
#define ARRSIZE 100000
class Vectorization
{
private:
    int mWorkCount;
    __int64 mTotalVectorTime;
    __int64 mTotalNoVectorTime;
    __int64 mNowVectorTime;
    __int64 mNowNoVectorTime;
    float mMinImproveTime;
    float mMaxImproveTime;
    int mPerformDecreseCase;
    int mPerformIncreseCase;
    int mTotalWorkCount;
public:
    Vectorization() : mWorkCount(0), mTotalVectorTime(0), mTotalNoVectorTime(0),
        mNowVectorTime(0), mNowNoVectorTime(0), mMinImproveTime(0.f), mMaxImproveTime(0.f),
        mPerformDecreseCase(0), mPerformIncreseCase(0), mTotalWorkCount(0)
    {}
    void CalculateWorkTime(float* a, float* b, int arrsize, bool isVector)
    {
        __int64 t1;
        __int64 t2;
        for (int i = 0; i < arrsize; i++)
        {
            a[i] = b[i] = i;
        }
        QueryPerformanceCounter((LARGE_INTEGER*)&t1);
        if (isVector)
        {
            #pragma loop(vector)
            for (int i = 0; i < arrsize; i++)
            {
                a[i] += b[i];
            }
        }
        else
        {
            #pragma loop(no_vector)
            for (int i = 0; i < arrsize; i++)
            {
                a[i] += b[i];
            }
        }
        QueryPerformanceCounter((LARGE_INTEGER*)&t2);
        if (isVector)
        {
            mTotalVectorTime += mNowVectorTime = t2 - t1;
        }
        else
        {
            mTotalNoVectorTime += mNowNoVectorTime = t2 - t1;
        }
    }
    void CalcNowWorkImprovePerform()
    {
        float ImproveRate = 100.0f - (float)mNowVectorTime / (float)mNowNoVectorTime * 100.0f;
        if (ImproveRate < mMinImproveTime)
        {
            mMinImproveTime = ImproveRate;
        }
        else if (ImproveRate > mMaxImproveTime)
        {
            mMaxImproveTime = ImproveRate;
        }
        if (ImproveRate < 0)
        {
            mPerformDecreseCase++;
        }
        else
        {
            mPerformIncreseCase++;
        }
        cout << "현재 벡터화 작업시간 :: " << mNowVectorTime << endl;
        cout << "현재 비벡터화 작업시간 :: " << mNowNoVectorTime << endl;
        printf("현재 성능 향상 비율 :: %.2f %%\n\n", ImproveRate);
        mTotalWorkCount++;
    }
    void CalcTotalWorkImprovePerform()
    {
        float improveRate = 100.0f - (float)mTotalVectorTime / (float)mTotalNoVectorTime * 100.0f;
        cout << "총 벡터화 작업시간 :: " << mTotalVectorTime << endl;
        cout << "총 비벡터화 작업시간 :: " << mTotalNoVectorTime << endl << endl;;
        printf("최저 성능 향상 비율 :: %.2f %%\n", mMinImproveTime);
        printf("최고 성능 향상 비율 :: %.2f %%\n", mMaxImproveTime);
        printf("평균 성능 향상 비율 :: %.2f %%\n\n", improveRate);
        cout << "성능 감소 케이스 :: " << mPerformDecreseCase << "회" << endl;
        printf("성능 감소 케이스 비율 :: %.2f %%\n\n", (float)mPerformDecreseCase / (float)mTotalWorkCount * 100.f);
        cout << "성능 향상 케이스 :: " << mPerformIncreseCase << "회" << endl;
        printf("성능 향상 케이스 비율 :: %.2f %%\n\n", (float)mPerformIncreseCase / (float)mTotalWorkCount * 100.f);
        cout << "총 성능 비교 횟수 :: " << mTotalWorkCount << "회" << endl;
    }
};
 
int main()
{
    Vectorization v;
    float fArr1[ARRSIZE];
    float fArr2[ARRSIZE];
    for (int i = 0; i < 10000; i++)
    {
        v.CalculateWorkTime(fArr1, fArr2, ARRSIZE, true);
        v.CalculateWorkTime(fArr1, fArr2, ARRSIZE, false);
        v.CalcNowWorkImprovePerform();
    }
    v.CalcTotalWorkImprovePerform();
}

 

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

'C++' 카테고리의 다른 글

[C++11] enum class  (1) 2017.07.17
[C++ 11] static_assert  (0) 2017.05.23
[C++ 11] Range-Based For  (0) 2016.11.01
[C++ 11] Scoped Lock  (0) 2016.11.01

Multi thread 프로그래밍을 할때 현재 thread가 작업하는 메모리를 다른 thread에 덮어쓰거나 잘못 사용하는 일이 발생하지 않도록 주의해야한다.

이러한 문제를 대비하기 위한 기법이 바로 thread 동기화인데 Critical Section, Semaphore, Mutex 등이 있다.

이러한 것들을 사용하지 않는다면

 

Tread 동기화를 사용하지 않은 스레드 작업

#include <iostream>
#include <Windows.h>
#include <thread>
#include <memory>
#include <mutex>
using namespace std;
int iArr[500];      // 두 thread가 작업할 메모리 공간

void test1()    // test1 함수는 iArr에 0을 채운다.
{
    for (int i = 0; i < 500; i++)
    {
        iArr[i] = 0;
        Sleep(1);
    }
}

void test2()    // test2 함수는 iArr에 1을 채운다.
{
    for (int i = 0; i < 500; i++)
    {
        iArr[i] = 1;
        Sleep(1);
    }
}

int main()
{
    // 각 함수를 스레드로 작동
    thread t1(test1);
    thread t2(test2);

    // 두 함수가 끝나기를 기다린다.
    t1.join();
    t2.join();

    // 결과값 출력
    for (int i = 0; i < 500; i++)
    {
        cout << iArr[i];
        if ((i +1) % 50 == 0)
        {
            cout << endl;
        }
    }
}

 

 

위의 결과 처럼 중간 중간 값을 덮어씌워서 오작동을 일으킬 수 있다.

 

하지만 위에서 말한 thread 동기화 기법을 사용하면 이 문제는 해결된다.

 

 

 

Mutex를 사용한 thread 작업

#include <iostream>
#include <Windows.h>
#include <thread>
#include <memory>
#include <mutex>
using namespace std;

int iArr[500];
mutex m;    // Thread Lock을 걸 Mutex 클래스

void test1()
{
    m.lock();   // 메모리에 lock을 걸어 다른 thread에서 사용하지 못하게 한다.
    for (int i = 0; i < 500; i++)
    {
        iArr[i] = 0;
        Sleep(1);
    }
    m.unlock(); // 메모리에 대한 작업이 끝난 이후에 lock을 해제한다.
}

void test2()
{
    m.lock();
    for (int i = 0; i < 500; i++)
    {
        iArr[i] = 1;
        Sleep(1);
    }
    m.unlock();
}

int main()
{
    // 각 함수를 스레드로 작동
    thread t1(test1);
    thread t2(test2);

    // 두 함수가 끝나기를 기다린다.
    t1.join();
    t2.join();

    // 결과값 출력
    for (int i = 0; i < 500; i++)
    {
        cout << iArr[i];
        if ((i +1) % 50 == 0)
        {
            cout << endl;
        }
    }
}

 

 

Mutex를 사용하면 처음 lock을 건 thread에서 작업이 끝난 이후에야 다른 thread에서 그 메모리에 접근해서 작업이 가능하기 때문에 모든 배열에 1이 출력이 된다.

 

 

 

 

이렇게 별 문제가 없어 보이는 thread lock에는 문제가 있는데 바로 Race Condition이다. 이 race condition은 일반적으로 1번 thread와 2번 thread가 있고 데이터가 담긴 메모리 A, B가 있을 때,  1번 thread가 A메모리에 lock을 건 상태에서 B메모리에 작업을 하려고 하고, 2번 thread는 B메모리에 lock을 건 상태에서 A메모리에 작업을 하려고 할때 발생한다. 이렇게 되면 1번 thread와 2번 thread는 서로 자신의 작업이 끝나야 각각의 메모리의 lock 해제하는데 서로에게 lock이 걸린 메모리 때문에 작업을 그 이후로 진행할 수 없기 때문에 프로그램은 작동을 정지하고 만다. 이런 상황을 다른 말로 dead lock, 교착상태라고도 한다.

 

하지만 scoped lock은 사실 이런 완벽한 교착 상태를 예방하기 위한 것이라기 보다는 사소한 프로그래머의 실수를 방지하기 위한 것이다. 다음의 코드를 보자.

 

프로그래머의 실수!

#include <iostream>
#include <Windows.h>
#include <thread>
#include <memory>
#include <mutex>
using namespace std;
int iArr[500];
mutex m;
void test1()
{

    // 이 프로그래머는 훌륭하게 lock을 걸었지만
    m.lock();
    for (int i = 0; i < 500; i++)
    {
        iArr[i] = 0;
        Sleep(1);
    }
    // unlock을 까먹고 하지 않았다!
}

void test2()
{
    m.lock();
    for (int i = 0; i < 500; i++)
    {
        iArr[i] = 1;
        Sleep(1);
    }
    m.unlock();
}

int main()
{
    thread t1(test1);
    thread t2(test2);
    t1.join();
    t2.join();
    for (int i = 0; i < 500; i++)
    {
        cout << iArr[i];
        if ((i +1) % 50 == 0)
        {
            cout << endl;
        }
    }
}

 

위의 코드처럼 실수로 thread lock을 건 이후에 작업이 끝나고 unlock을 까먹는다면 2번 thread는 1번 thread가 걸어둔 lock이 해제되기를 영원히 기다릴 것이다. 위 코드처럼 간단한 thread 예제라면 이러한 문제를 쉽게 찾아내겠지만 수만줄을 넘어가고 여러 종류의 thread가 여러 개 돌아가는 커다란 프로그램에서 저런 기억하기 어려운 사소한 실수를 범하게 된다면 얼마나 긴 시간을 허비하게 될까?

 

 

 

 

그래서 나온 것이 scoped lock이라는 것인데 이것의 원리는 매우 간단하다. 우리가 사용하는 Mutex를 하나의 클래스로 가볍게 감싸는 것이다. 그리고 클래스의 생성자가 실행될 때 lock()을 실행하고 클래스의 소멸자가 실행될 때 unlock()을 실행해 주는 것이다.

이것은 프로그래머가 직접 구현해도 될 정도로 간단한 작업이지만 표준 C++에서는 이미 지원되고 있으니 해당 기능을 사용하면 된다.

 

Scoped Lock 사용법

#include <iostream>
#include <Windows.h>
#include <thread>
#include <memory> // Scoped lock 기능을 사용하기 위해 include 해야하는 header
#include <mutex>
using namespace std;
int iArr[500];
mutex m;
void test1()
{
    lock_guard<mutex> g(m);      
    // lock_guard 클래스의 템플릿에 mutex 클래스를 넣고 생성자에 우리가 사용하는 mutex 객체를 넣어주면 된다.
    // lock_guard 객체가 생성될 때 자동으로 thread에 lock이 걸린다.
    for (int i = 0; i < 500; i++)
    {
        iArr[i] = 0;
        Sleep(1);
    }
    // 그리고 함수가 끝날 때 or 스코프를 벗어날 때 자동으로 lock_guard 객체가 소멸되면서 thead lock이 해제된다.
}
void test2()
{
    lock_guard<mutex> g(m);
    for (int i = 0; i < 500; i++)
    {
        iArr[i] = 1;
        Sleep(1);
    }
}
int main()
{
    thread t1(test1);
    thread t2(test2);
    t1.join();
    t2.join();
    for (int i = 0; i < 500; i++)
    {
        cout << iArr[i];
        if ((i +1) % 50 == 0)
        {
            cout << endl;
        }
    }
}

 

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

'C++' 카테고리의 다른 글

[C++11] enum class  (1) 2017.07.17
[C++ 11] static_assert  (0) 2017.05.23
[C++ 11] Auto Vectorization  (1) 2016.11.01
[C++ 11] Range-Based For  (0) 2016.11.01

프로그래밍에서 사용되는 용어의 주된 특징은 그 원어는 거의 전부(어쩌면 거의가 아니라 그냥 전부)가 영어에서 온다는 것이다. 그렇기 때문에 발생하는 문제는 비영어권인 지역의 사람이 정보를 접하기 위해서는

  1. 영어로 된 자료를 직접 번역해서 읽는다.
  2. 번역된 자료를 읽는다.

이 두 가지 중 하나를 선택해야 한다. 물론 오랫동안 프로그래밍 해온 개발자로서는 제대로 된 정보를 얻기 위해서는 1번이 좀 더 나은 선택이라는 것을 알고 있고 어느 정도 영어에 친숙해진 이후라 1번을 주로 택하게 되겠지만 아직 프로그래밍을 시작한지 얼마 안된 개발자/지망생은 일반적으로 영어에 친숙하지 않고 번역된 자료를 선호하는 경향이 좀 있기도 하고, 쉽게 접할 수 있는 자료가 번역된 자료이기 때문에 2번을 주로 하게 된다.

 

물론 번역된 쉽게 접할 수 있는 자료라는 것은 아주 좋은 것이지만 몇 가지 문제가 항상 읽는 사람을 큰 혼란에 빠뜨린다.

  1. 용어의 과도한 한글화로 인한 원래 용어를 알 수 없게 되는 경우
  2. 용어의 한글화를 하는 도중에 그 단어의 표면적인 뜻만을 번역해서 그 용어가 의미하는 바를 알 수 없게 되는 경우
  3. 딱딱한 번역체로 인해서 아주 읽기 힘든 글이 되는 경우

뭐... 번역자들에게도 고충이 없겠냐마는 위의 세 가지 문제는 언제나 외국의 문물을 받아들이려는 학생을 힘들게 한다.

 

이번에 surface라는 용어에서는 그런 2번의 문제를 매우 심하게 느꼈는데 DXGI_USAGE의 열거형들을 조사하면서 이 surface라는 단어를 만났다. 그래서 이 열거형들의 내용이 번역된 자료를 찾아나섰는데 거기엔 이 surface를 다른 설명없이 그냥 표면이라는 단어 하나로 번역해 놓은 것이었다.

 

Direct3D의 surface라는 용어를 표면이라는 단어로 진정한 용어의 뜻 대신 그냥 표면적인 단어의 뜻만 보여주는 상황이라니... 이 얼마나 어이없는 일인가?

이것은 그리 똑똑하지는 못한 내 생각이지만 번역을 할때 이 원칙을 세워 지켰으면 좋겠다.

 

한글로 번역했을때 그 뜻이 쉽게 혹은 누구나 알기 쉽게 드러나지 않는 용어는 섣불리 한글로 번역하지 않고 그 용어에 대한 충분한 설명을 곁들일 것.

 

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

+ Recent posts