2020-09-28

작업관리자의 ‘GPU 엔진’에서 GPU Copy가 의미하는 것


 

1.     작업관리자를 열었다가 희안한걸 보게 됐다.

 

평소에도 컴퓨터의 반응이 굼떠지면 제일 먼저 확인하는 곳이 바로 작업관리자다. 그도 그럴 것이.. 여기에서 거의 대부분의 문제를 해결할 수 있었기 때문이기도 하다. 그런데 열어보다가 궁금한 점이 하나 생겼다. 언제부턴가 ‘GPU 엔진이라는 항목이 생겼고, 거기엔 또 GPU Copy 3D같은 것들이 보였다. 이게 대체 뭘까?

 

2.     GPU 엔진이 하는 일은 뭘까?

 

당연히 게임! 이라고 대답하기엔 호기심이 해결되지 않는다. 초창기 그래픽카드의 역할은 모니터에 그림을 그려주는 것이었다. 우리가 모니터를 통해 글자를 볼 수 있는 것도 모두 글자의 생김새를 모니터에 점을 찍어 나타내고 있는 것이다. 1990년대까지만 하더라도 이러한 간단한 작업은 CPU가 처리해주었지만, 그래픽 작업을 전문적으로 수행하는 소프트웨어 및 게임을 위해 GPU하게 . 요즘은 가상화폐 채굴과 인공지능을 위한 GPU가 더 각광받는 것 같긴 하다.

그런데 운영체제에서도 GPU를 적극적으로 활용하고 있다. 대표적으로 윈도우 7 사용자라면 멋을 위해 사용해봤을 법한 Windows 7 Aero Theme이 있다.

유리처럼 반짝이는 이 기능을 더 예쁘게 사용하고 싶어서 컴퓨터도 새로 맞추고 이런저런 테마를 적용해보고 가꿔본 기억이 난다. 그런데 이 기능은 보기보다 GPU 메모리를 많이 먹을 뿐더러, CPU 자원까지 잡아먹는다!

윈도우에서 열려있는 창(window)의 시각 효과를 담당하는 것이 바로 Desktop Window Manager (DWM)이다. 위에서 언급한 유리 창틀 효과를 비롯해 3D 창 전환 애니메이션, 화면의 플립(Flip) 및 고해상도 지원 등을 담당하고 있다. 영상 제작에서 자주 쓰이는 composition 은 라틴어인 componere에서 유래했는데, 이는 우리말로 같이 놓다(put together)’라는 뜻이다. 데스크탑에서 창들을 위치별로 그려내는 일을 하는 녀석이 바로 DWM이라고 생각하면 된다.

SuperUser 에 따르면 Visual Studio, PHPStorm, Aptana Studio, Chrome, Firefox, IE 등등 GPU 메모리를 소비하지 않는 프로그램을 찾기 힘들 정도이고, GPU 코어의 사용량이 높지 않아도 GPU 메모리가 일정 수준을 넘어서게 되면 OS 차원에서 관리하기 위해 Desktop Compositing의 일부 기능을 정지시켜 GPU 메모리를 절약한다. GPU 메모리의 약 75% 사용량에 도달할 시 윈도우는 데스크탑 컴포지션을 비활성화시키지만 전체화면 애플리케이션을 사용하고 있는 경우엔 데스크탑 컴포지션이 비활성화되지 않으며, 이 때문에 전체화면으로 게임을 하는 경우엔 게임의 요구사양을 충분히 만족하는데에도 ‘Windows has detected that your computer’s performance is slow’ 메시지가 뜰 수 있는 것이다.

이처럼 운영체제 자체에서도 GPU는 많이 사용되고 있다. 뿐만 아니라 크롬에서도 GPU 가속 설정을 지원하고 있다. 여담으로 크롬에서 하드웨어 가속 설정에 관한 토론을 에서 찾을 수 있었다. 꺼야 할지 켜야 할지 모르겠다면 위의 토론을 읽어보고 판단하면 좋을 것 같다.

 

3.     성능탭에서 GPU 사용 환경을 체크할 수 있다.

 

 

그래서 다시 본래의 호기심으로 돌아오자면.. ‘OSGPU를 쓰는 것까진 알겠는데, 그럼 3DCopy 이런건 뭘까싶다. 이는 을 받아 프트 를 통해 확인할 수 있었다.

 

 

A GPU engine represents an independent unit of silicon on the GPU that can be scheduled and can operate in parallel with one another. For example, a copy engine may be used to transfer data around while a 3D engine is used for 3D rendering. While the 3D engine can also be used to move data around, simple data transfers can be offloaded to the copy engine, allowing the 3D engine to work on more complex tasks, improving overall performance. In this case both the copy engine and the 3D engine would operate in parallel.

번역: GPU 엔진은 스케줄화 될 수 있고 병렬로 작동할 수 있는 GPU의 독립적인 단위를 말한다. 예를 들어서, copy 엔진은 3D 엔진이 3D 렌더링을 진행하는 동안에 데이터를 상호 교환하는 데에 사용될 수 있다. 3D 엔진을 사용해서 데이터를 전송할 수도 있지만, 3D 엔진이 다른 복잡한 작업을 할 수 있도록 copy 엔진에게 데이터 전송 업무를 분담함으로써 전체적인 성능 향상에 기여한다. 이런 경우엔 copy 엔진과 3D 엔진이 모두 병렬적으로 작동한다.

 

GPU를 도식화한 그림을 위와 같다. 기본적으로 작업관리자는 4개의 엔진을 화면에 표시해준다. 화면에 표시할 엔진을 선택하는 기준은 이 엔진이 얼마나 관심있게 볼만한 엔진인가이라고 한다. 원한다면 사용자가 엔진 이름을 클릭해서 다른 엔진의 상태들을 모니터링할 수 있다.

그런데 엔진들의 이름들이 반드시 역할에 종속적인 것만은 아니다. 3D 엔진이 열일하고 있을 때엔 compute 엔진이 data transfer를 담당하기도 하고, GPU 드라이버가 판단하기에 영상 재생 중 decode 엔진이 바쁘다면 주어진 작업을 여러 개의 엔진을 조합시켜 수행할 수도 있다.

또한 ‘Copy’는 시스템 메모리에서 GPU 메모리로 데이터를 복사해오는 것을 의미한다.

 

VidSch가 바로 GPU 엔진을 사용하고자 하는 프로세스들 사이에서의 우선순위 결정 및 중재를 담당하고 있다.

GPU 엔진과 GPU 코어를 구분할 필요가 있다. GPU 엔진은 수많은 GPU 코어들로 구성되어 있다. 예를 들어서 3D 엔진은 대략 천 여개의 코어들로 구성되어 있으며, 이들은 그룹화되어 관리되기 때문에 통틀어서 엔진이라고 부르는 것이다.

 

 

2020-09-22

다빈치 리졸브의 타임코드가 1시간부터 시작하는 이유

0. 파이널 컷, 다빈치 리졸브 등의 도구에서 동영상 편집 위치가 1시간부터 시작되는 이유는 무엇일까? 어째서 0시간부터 시작하지 않았을까? 뭔가 오래된 방송 표준 규격 때문이었던 걸까?

1. 슬레이트, 카운트 다운, 테스트 신호 등을 위해 첫 번째 사진을 찍기 전에 공간을 남겨 두면서도, 비디오의 실행 시간을 비교적 쉽게 계산할 수 있었기 때문이다. 이는 역사적으로 방송에서 사용된 비디오 테이프에 근원이 있다.

출처: StackExchange

2. 항상 그런 것은 아니지만 이러한 형태를 사용하는 것이 유리한 경우들이 있다. 초기 타임코드 장비 및 이후의 타임코드-종속성 소프트웨어들은 23:59:59:XX에서 0으로 넘어가버리는 버그가 있었다. 그래서 이를 피하기 위해 동영상을 1시간부터 재생시키는 것이 계산하기에 쉬웠던 것이다. 이는 설정에 따라 다르며, 1, 10시간 등 여러 숫자가 쓰일 수 있지만, 그 중에서 1시간은 특히 계산에 편리하기 때문에 사용되었던 것으로 생각된다.

출처: reddit

3. 또한 많은 프로덕션사에서 1번 테이프를 1시간부터, 2번 테이프를 2시간부터 시작하도록 배치하는 것이 관용적으로 많이 이용된 방법이다.

출처: avid.secure.force.com

4. 난 싫어! 숫자는 0부터 세는거야!”라고 생각하는 사람이 있다면 을 참조하여 시작 시간을 변경하면 된다.

2020-09-10

구글 코랩에서 셀레니움 사용하기

0.     셀레니움을 리눅스에서 사용하기

 

은 브라우저와 같은 환경으로 웹 스크래핑(크롤링)을 자동화해주는 소프트웨어이기도 하다. 브라우저와 같은 방식으로 작동해 자바스크립트, AJAX, CSS등을 로드하고 적용하기 때문에 화면에 보이는 요소를 그대로 추출해내기 쉬워서 많은 초보자들이 애용하고 있다.


 

셀레니움은 윈도우 말고도 리눅스와 맥 버전을 지원하고 있다. 그러나 여기에서 사용되는 리눅스 파일은 바이너리 파일이다. 왜인지는 모르겠으나, 해당 바이너리 파일만으로는 실행되지 않고

“WebDriverException: Message: Service chromedriver unexpectedly exited. Status code was: -6”

라는 에러를 일으켰다. 해당 에러를 Stack Overflow에서 “chromium-chromedriver”를 설치해줘야 한다는 것을 알게 됐다. 그래서 친절히도 그가 를 통해 간단하고 빠르게 코드를 구현할 수 있었다.

 

 

1.     코랩에서 테스트

 

모든 과정을 담은 코드는 아래와 같다. 편의를 위해 GitHub 도 함께 첨부하였다.

코랩에 셀레니움을 설치합니다.

!apt-get update

!apt install chromium-chromedriver

!pip install selenium

!cp /usr/lib/chromium-browser/chromedriver /usr/bin

 

셀레니움을 임포트하고크롬 드라이버를 PATH 추가합니다.

from selenium import webdriver

import time

import sys

sys.path.insert(0,'/usr/lib/chromium-browser/chromedriver')

 

# Headless 옵션을  셀레니움 객체를 생성합니다.

chrome_options = webdriver.ChromeOptions()

chrome_options.add_argument('--headless')

chrome_options.add_argument('--no-sandbox')

chrome_options.add_argument('--disable-dev-shm-usage')

driver = webdriver.Chrome('chromedriver',options=chrome_options)

 

구글 검색 예제

driver = webdriver.Chrome('chromedriver',options=chrome_options)

 

try:

    driver.get('https://www.google.com/')

    time.sleep(1)

 

    element = driver.find_element_by_name('q')

    print(element)

    element.send_keys("안녕 구글")

 

    element.submit()

    time.sleep(5)

 

    element = driver.find_element_by_xpath('//*')

    element = element.get_attribute('innerHTML')

    print(element)

 

except Exception as e:

    print(e)

    driver.close()

finally:

    driver.close()

 

 


2020-09-09

크롤링이 나쁜가


0. 크롤링이 나쁜가

크롤링이 나쁜건지 모르겠다.. 내가 웹사이트를 운영하게 된다면 나도 크롤러의 악성 접근을 차단하기 위해 어떤 조치를 내릴 것 같긴 하다. 그러나 크롤러도 이 사이트의 방문자; 그들이 내 데이터를 수집해가는 행위를 방해하는 것은 또 한 명의 고객을 잃는 것과 같다.

1. 크롤링은 원래 나빴다

하지만 서버비는 조상님이 내주던가? 크롤러가 내 웹사이트를 다녀가면서 발생시키는 트래픽은 고스란히 내 통장의 이체 금액과 비례하게 된다. 트래픽이 곧 돈이다. 내가 그들의 편의와 데이터 수집을 위해 돈을 지불할 필요는 없지 않은가. 오히려 그들이 내게 데이터를 요청하려 한다면 이메일로 그 데이터를 사들이고 싶다고 제안해와야 한다. 그게 순리 아닌가데이터가 돈이 되는 세상이다.

2. 하지만 데이터는 공개되어야 한다.

정말 보안성이 중요한 데이터(예를 들면 개인정보)가 아니라면 공개되어도 무방하지 않을까 싶다. 애초에 사이트 접속자들이 보라고 만들어 놓은 콘텐츠들이니 이제와서 무리하게 콘텐츠를 소비했다고 욕할 수도 없는 노릇이다. 비슷한 일례로 sci-hub같은 사이트가 있다. 해당 사이트는 엘제비어 같은 대형 출판사의 서버를 해킹해 논문들을 무료로 호스팅한 서비스이다. 오픈 액세스 운동에 영향을 미쳤다는 평을 받고 있으며, 이에 대한 갑론을박도 치열하다. 내가 데이터를 열심히 생산해냈는데 다른 누군가가 이를 무단으로 사용하고 있다면 확실히 분노할 만한 일이다. 그러나 데이터 생산과 유통, 분석 방법 및 노하우 같은 무형 자산까지 크롤링해가진 못했다. 쉽게 말하면 내가 데이터를 만들어내는 방식까지 카피하지 못한다면, 내게 의존할 수 밖에 없다

3. 적절한 크롤링 수위를 유지한다면 관용적으로 허용해주자.

어떤 서비스를 제공하기 시작하면 악용하는 사용자가 분명히 나타난다. “악용하는 사용자가 나쁜거지~ 서비스 제공자가 나빴냐?”라고 물을 수도 있다. 물론 악용하는 사용자가 나쁘다. 그러나 게임하라고 플스넷을 만들었더니 플스넷을 해킹하는 데에 시간을 쏟는 해커들이 나타났고, 그 해커 잡겠다고 발악한 소니는 각종 해커 그룹이 꼬이게 만드는 빌미를 제공해서 2011 PNS 를 야기한 선례가 있다. 물론 해킹이 나쁜 것이지만, 해커들 어그로 제대로 끌어서 거하게 말아먹은 소니의 실수를 보고 칭찬할 사람은 아무도 없으리그렇다고 악성 사용자와 타협해야 하느냐, 그건 또 아니라고 본다. 지나치게 서버에 부담을 주는 수준이 아니라면 집행유예와 같은 개념을 도입하는 것도 좋다는 이야기를 하고 싶었을 뿐이다. 과도한 규제는 반발을 일으킨다. 많은 사용자들이 당대 사회통념상 참고 넘어가줄 수 있는 수준이라면 애교로 봐주고 방치한다는 선택지를 따를 수도 있을 것이다. ‘상식적으로 이건 선 넘었지라는 수준이라면 그에 대한 강경한 대응도 많은 이들의 공감을 얻어낼 수 있을 것이다.

제 코드에 문제가 있어요! 도와주세요!




파이썬 커뮤니티에선 맞닥뜨린 문제로 인해 고통받는 영혼들의 울음소리가 끊이질 않는다. 대개 코딩 좀 할 줄 안다는 사람들은 이미 현업에서 뛰고 있다 보니 바빠서 답변을 해주지 못할 수도 있겠다. 그래서 파이썬 중급자를 자처하는 난 그들의 문제를 함께 마주보고 해결해주기 위해 부단히 노력한다. 봉사정신을 키우고 싶어서 그렇게 행동한다기보단 (나도 그렇게 시간 남아도는 사람이 아니거니와, 그렇게 착해빠진 사람도 아니다) 나도 처음 보는 그 문제를 통해 더 많은 문제를 접하고 해결해나갈 방법을 고민할 기회를 얻는다는 데에 더 큰 의의를 두고 있다. 실제로 다른 사람의 문제를 함께 고민하는 것은 나의 실력 향상에 많은 도움이 되었다. 그래도 딴에는 중급자라고, 그들의 코드를 보면 한숨이 나오곤 한다.

왜 코드를 이렇게 짰지…?’

분명히 바퀴가 4개 달려있는 자동차는 맞는데 바퀴 두개는 아래에, 나머지 두개는 천장에 달려있다. 그래놓곤 이 자동차가 왜 멀쩡하게 다른 자동차들처럼 굴러가지 않느냐고 묻는다. 이쯤 되면 커뮤니티의 사람들은 이렇게 반응한다.

구글에 자동차를 검색해서 어떻게 생겼는지 보고 오세요

이는 운송수단인 자동차가 보편적으로 어떤 골격을 가지고 있는지를 보고 배우라는 의미이다. 프로그래밍 언어들은 자신만의 자료형과 문법을 가지고 있다. 문자열, 정수, 실수, 리스트, 배열 등등 어느 언어에서나 자주 사용되는 자료형은 대개 특징들이 비슷하고 문법도 비슷하다. 문법도 마찬가지다. 연산자, 반복문(while문 포함), if, try/except, 함수의 결과값 반환 등 프로그래밍 언어에게 지시하는 방법도 어느정도 효율적인 방식이 정립되어 있다. ~고급 사용자들은 이미 키보드를 쳐볼 만큼 쳐봤기 때문에 기본적인 사용법은 숙지하고 있다. 하지만 초보자들은 이제 막 배우는 단계이기 때문에 프로그래밍 언어들이 이러한 명령문들의 흐름으로 이루어져 있다는 개념 자체를 배우는 것만으로도 머리에 과부하가 걸릴 것이다. 그 막막함은 나도 이해한다, 나도 새로운 무언가를 배울 때마다 느끼는 감정이니까.
많은 중~고급자들은 힘들어하는 초보자들의 이상한 자동차를 당장 굴러가는 자동차로 수정해주려는 경향이 있다. 그래서 그들이 수정해준 코드는 다음과 같다.


바퀴가 부족하니까 안 굴러가죠. 바퀴 4개가 땅바닥에 붙어있어야 굴러가죠.’

틀린 말은 아니다. 바퀴 수가 불필요하게 많아졌지만 아무튼 굴러간다. 심지어 이 수정된 자동차는 무려 천장으로 달릴 수도 있다(!). 중력이 거꾸로 된 세계(거꾸로 된 파테마)에서도 문제없이 운행 가능하다.
그런데 질문자는 이제와서 다음과 같은 요구사항을 추가하게 된다.

이거 사실 정글에서 쓰일 이동수단이었거든요. 이 자동차는 제 목적과 부합하지 않아요.’

미치고 팔짝 뛸 노릇이다. 애초에 그런 목적이었더라면 자동차가 아니라 궤도전차를 구상했을 것이다. 그제서야 질문자의 자동차 디자인에 조금 납득이 가기 시작한다. 천장에 달아놓은 바퀴는 그저 덩굴을 헤쳐나가고 싶은데 마땅한 디자인을 만들 여력이 없어서 이렇게 만들었겠거니도달해야 할 목적지가 설산 꼭대기라면 스노우 모빌을, 해변이었다면 수륙양용 호버크래프트를, 하이퍼루프였다면 자기부상열차를 디자인했을 것이다.
이렇게 조용히 디자인을 상상하던 내게 질문자는 또다시 놀라운 조건 하나를 추가하게 된다.

정글의 산에 터널을 뚫을 이동수단이 필요해요

그가 필요했던 것은 TBM이었다.


아예 처음부터 뜯어고쳐야 했던 것이다. 기존의 코드를 수정하는 수준이 아니라 더 나은 (다른) 틀을 가져와서 내 목적에 맞게 개조해야 했던 것이었다. 이제야 질문자가 처음에 프로토타입으로 만들었던 자동차(?)가 왜 그런 모양이었는지를 깨닫는다.

이 과정에서 가장 핵심은 질문자가 만드려는 코드의 목적이었다. 어째서 이 코드가 필요한가, 이 코드가 궁극적으로 수행할 작업은 무엇인가, 그로 하여금 어떤 결과를 얻길 바라는가. 이러한 질문을 스스로에게 던져보고, 그 질문으로 검색을 해봐야 하며, 거기서도 답을 찾지 못했을 경우엔 창피해하지 말고 숙련자에게 질문해야 한다. 질문할 때엔 자신이 이런이런 목적으로 디자인했고, 원하는 결과물은 저런저런 모양이었는데, 그런그런 문제들이 터져서 고생했다는 식으로 자신의 상황을 적극적으로 알려야 한다.
코드를 직접 작성하지 않아도 되는 경우가 굉장히 많다. 팩토리얼(factorial)을 구하는 방법, 소수를 구하는 방법, n개의 요소를 갖고 있는 집합에서 조합 가능한 순열을 구하는 방법 등이 이미 사용 가능한 함수형 라이브러리로 제공되고 있다. 이러한 라이브러리들은 간편하고, 빠르고, 효율적이기까지 하며 검증도 완료되어 있다. 물론 공부를 하는 입장에서는 알고리즘을 직접 짜보는 연습을 해보는 편을 추천하고 있지만, 당장 발등에 불 떨어져서 결과를 만들어내야 한다거나 혹은 일반인으로서(비전문가로서) 깊게 파고들기엔 귀찮고 그냥 이런 기능을 하는 라이브러리가 있구나 하는 수준으로 넘어가고 싶은 사람들은 그 수준에서 사용해도 무방하다. 그걸 다 파고들어 공부하기엔 학습량이 기하급수적으로 늘어나거니와, 이걸로 논문을 쓸 생각이 아니라면 이 정도로 사용하는 것이 바람직하기도 하다. 프로그래밍 격언 중엔 이런 말이 있다: 바퀴를 재발명하지 마라(Don't reinvent thewheel)’ 그 라이브러리에 대한 이해는 필요하되, 그걸 내 손으로 만들어내기 위해 고생할 필요는 없다. 있으면 가져다 쓰자.
하지만 라이브러리가 모든 기능을 전부 수행해주는 것은 아니다. 자동차에 탑승했다고 알아서 목적지까지 데려다주던가? (자율주행차 얘기는 지금 하지 말자…) 시동을 걸고, 이리저리 핸들을 돌리고, 감가속을 하고, 다른 차량들과 경쟁(?)해서 살아남아야 비로소 목적적에 도착할 수 있다. 이러한 과정은 코딩에서도 마찬가지이다. 이 라이브러리를 여기에 배치하고, 저런 옵션을 주고, 디버깅을 해서 원치 않는 작동을 차단해야 목적을 이룰 수 있다. 이를 위해 운전자는 운전 스킬(코딩 스킬)을 숙달해야만 한다. 이는 결국 투자한 시간, 즉 경험으로 인해 노하우가 늘게 된다.

저와는 다르게 뚝딱뚝딱 검색해서 바로 해결하시는거 보고 대단하다고 생각했어요

목적이 명확하다면 해당 질문을 구글에 집어넣어 검색해보는 것만으로도 답이 나오는 경우가 많다. 내가 마주한 문제가 이 세상에서 유일한 문제일 가능성은 매우 희박하다. 이미 많은 사람들이 겪어보고 해결해나간 문제일 가능성이 높다. 코딩 능력의 절반은 검색 능력이라는 말이 있을 정도로 구글링은 높은 중요성을 갖는다. 다만, 질문을 영어로 해야 한다. 이 부분에 대해서도 할 말이 많지만, 내 수면시간이 부족한 관계로생략한다. 한국어로 검색해도 많은 자료들이 나오긴 한다. 기초적인 수준(예를 들어서, 반복문을 어떻게 쓰는지 모르겠다거나 등등)의 질문이라면 우리말로 잘 정리된 강좌들을 찾아보는 편이 훨씬 도움이 된다. 그러나 문제의 특이성(Specificity)이 높다면 한국어로 검색해서 해답을 찾을 가능성이 낮다. 그럴 땐 영어 실력이 부족하다고 포기하지 말고, 번역기라도 돌려서 영어로 검색하는 습관을 들이는 편이 좋다.

모른다는 사실조차 모르고 있는 상태에서 질문하기

고급 사용자들에게 질문을 던지면 대개 추상적이고 이해하기 힘든 단어들이 나열된 답변을 받게 된다. 그것은 어쩌면 내가 모른다는 것조차도 모르는 미지의 영역일지도 모른다. 나는 네트워크맵을 만들면서 다음과 같은 문제에 직면한 적이 있었다. 네트워크의 구성원이 될 노드는 사람들의 아이디가 된다. 각 노드를 연결할 엣지의 두께는 두 사람 사이에서 얼만큼 활발한 교류가 있었는지에 따라 결정된다. 그래서 그 교류가 많을수록 해당 노드의 크기도 크게 그린다. 내가 가진 raw data는 각각의 아이디가 어떤 활동을 했는지에 대한 정보이고, 같은 활동을 한 다른 아이디를 찾아낸 뒤 그 정보를 이용해 노드의 크기를 결정해야 했다. 그래서 구성원들 사이에 조합 가능한 순열을 얻어야 했는데, 이걸 알고리즘으로 구현하려니 머리가 지끈거리기 시작했다. 그래서 위의 상황을 설명하는 것 대신에 보다 문제를 간결하게 추상화하여 아래와 같이 질문했다.


리스트 ['A', 'B', 'C']가 주어질 때, 두 개로 가능한 모든 조합 ['AB', 'AC', 'BC']의 형태로 반환하는 함수를 짜려고 하는데, 뭐라고 검색하면 좋을까요?
파이썬에서는 itertools 패키지에 combinationspermutation 함수가 위의 연산을 수행해준다. 한국어로 질문도 던졌고, 영어로도 ‘combinations’이라는 단어를 떠올리지 못해서 ‘find all possible pair in list’처럼 검색했다. 그리고 나오는 결과를 닥치는 대로 읽어 내려갔다. 결국 질문해놓고 자문자답했다.
특정 수준에 이르게 되면 (특이점이 오면) 더 이상 커뮤니티에 질문을 올리지 않게 된다. 질문을 해도 답변이 돌아오지 못할 것이라 추측하기 때문이다. 그렇게 되는 몇 가지 경우들이 있다. 첫째, 프로젝트의 규모가 커지고 복잡도가 올라가면서 해당 코드의 쓰임새를 온전히 이해하는 사람이 본인 뿐인 경우이다. , 머릿속의 아이디어를 구체화할 주체가 다름아닌 본인일 경우이다. 다른 누군가에게 자신의 아이디어를 구체적으로 (아주아주 구체적으로) 설명해줄 수 있는 수준이 되면, 다른 누군가에게 맡기는 것보다 자신이 진행하는 편이 더 효과적이다. 둘째, 해결하려는 문제가 지나치게 어려운 경우. 아무리 고수들이 모인 커뮤니티라 하더라도 해결하기 쉽지 않은 문제들은 두루 있기 마련이다. 이런 문제들에 대해 고수들이 추상화된 답변을 해줄 수는 있을지언정 해당 문제 자체를 해결할 수 있도록 도와줄 수는 없다. 그 사람도 모르니까 배운 다음에 대답해줘야 할텐데, 그 정도로 친절한 사람은 이미 어딘가에 불려가서 남의 일을 도와주고 있다. 지나치게 고수준의 지식이 요구되는 질문은 답변자가 등장하지 않을 수도 있다. 이럴 때에는 본인이 공부해서 다른 이들에게 지식을 전파해주도록 하자. 셋째, 너무 많은 시간이 드는 경우. 해결 방법은 알겠는데, 그걸 해결하기 위해 투자해야 할 시간이 길게 예상되는 경우이다. 벽돌깨기 게임에 공 하나를 주고 벽돌 10만개 깨라고 하면 어떤 반응을 보여줘야 할지 상상해보자. ‘이건 외주를 맡겨야지 왜 나한테 도와달라고 하는거야라는 반응을 보이고 싶을 것이다.

숙련자들도 결국 그만큼 시간과 공을 들여서 도달한 경지일 것이다. 초보자들도 시간을 들이면 언젠가는 고수준의 코딩을 할 수 있다. 물방울로 바위를 뚫는다는 마음가짐으로 정직하고 꾸준하게 접근해보자. ‘와 어떻게 저렇게 쭉쭉 진행할 수가 있지라며 나의 존경심을 받는 그 사람, 아마 모르긴 몰라도 해당 작업에 익숙해지기 위해 많은 시간을 소비했으리라.

2020-09-05

영어 문장 소리내서 읽어주기 (Windows 10 자체 기능)

0. 웹서핑을 하다가 영어 문장을 소리로 듣고 싶을 때가 있다.

그럴 때 종종 구글 번역기에 문장을 복사/붙여넣기를 해서

영어 문장을 읽곤 했는데

이젠 윈도우10에서 자체적으로 해당 기능을 지원하기 시작했다.





1. 윈도우10 빌드2004 버전부터 아래와 같은 기능을 지원하기 시작했다.


Win Key + '+ 키'를 누르면 '돋보기' 기능이 열리는데

듣고 싶은 문장 맨 앞을 (드래그하지 말고) 단순히 한 번 클릭한 다음

돋보기의 ▶ 버튼을 누르면 영어도 모두 읽어준다.





2. 좋다.

이외에도 유용한 단축키들을

마이크로소프트 고객지원 페이지에서 확인할 수 있다.