C# 6.0 완벽 가이드/ 병렬 프로그래밍

  • 이번 장에서는 다중 코어 프로세서의 활용을 목적으로 하는 다음과 같은 다중 스레드 API 들과 구축 요소들을 살펴본다.
    • PLINQ(Parallel LINQ; 병렬 LINQ)
    • Parallel 클래스
    • 작업 병렬성 구축 요소
    • 동시적 컬렉션(concurrent collection)
  • 이들은 모두 .NET Framework 4.0에서 도입되었다. 이들을 통틀어 PFX(Parallel Framework; 병렬 프레임워크)라고 부르기도한다.
    • 그리고 Parallel 클래스와 작업 병렬성 요소들을 합해서 TPL(Task Parallel Library; 작업 병렬 라이브러리)이라고 부른다.
  • 이번 장을 이해하려면 14장에서 말한 기본 개념들에 익숙해야 한다. 특히 잠근, 스레드 안전성, Task 클래스를 숙지할 필요가 있다.

PFX가 왜 필요한가?

  • 지난 10여년 사이에 CPU 제조사들은 단일 코어 프로세서에서 다중 코어 프로세서로 초점을 옮겼다. 이떄문에 예전처럼 그냥 CPU만 빠랄지면 단일 스레드 코드도 저절로 빨라지는 현상은 더는 기대할 수 없게 되었다. 이제 성능 향상을 위해서는 여러 개의 코어(core)를 제대로 활용해야 한다.
  • 서버 응용 프로그램들은 대부분 각 클라이언트 요청을 개별 스레드에서 처리하는 형태이므로 여러 코어를 활용하는 것이 어렵지 않다. 그러나 데스크톱 응용 프로그램은 그렇지 않다. 데스크톱 응용 프로그램에서 다중 코어를 활용하려면 프로그램 중 처리량이 많은 코드의 구조를 다음과 같은 형태로 개선해야 한다.
    1. 처리할 일거리를 더 작은 덩어리들로 분할(partitioning)한다.
    2. 각 덩어리를 다중 스레드 기법을 이용해서 병렬로 처리한다.
    3. 처리가 끝난 스레드들의 결과를 스레드에 안전한, 그리고 성능 효율적인 방식으로 취합(collating) 한다.
  • 이러한 개선을 고전적인 다중 스레드 적용 수단들을 이용해서 독자가 직접 수행할 수도 있지만, 그리 쉬운 일은 아니다. 특히 분할과 취합 단계가 까다롭다.
    • 게다가 다수의 스레드가 같은 자료를 동시에 다루는 경우 스레드 안전성 확보에 흔히 쓰이는 잠금 전략들을 그대로 적용하면 경합이 심해져서 성능이 떨어진다.
    • PFX 라이브러리들은 바로 이런 상황에 도움이 되도록 설계되었다.
  • 다중 코어 또는 다중 프로세서를 활용하는 프로그래밍을 병렬 프로그래밍(parallel programming)이라고 부른다. 병렬 프로그래밍은 그보다 더 넓은 개념인 다중 스레드 적용(multithreading)의 일부이다.

Continue reading

개발자도 궁금한 IT 인프라

제목 그대로 IT 인프라에 대한 이야기. 팟캐스트의 내용을 책으로 엮었다고 한다.

개인적으로는 DevOps 라는 분야에 대한 흥미와 하드웨어 관리에 대해 관심이 있어서 읽어봤는데, 읽기 전과 후의 지식 차이가 별로 없었다. 하드웨어에 대한 깊은 얘기는 아예 못 알아 듣고, 내가 알고 싶었던 부분에 대해서는 자세히 다뤄지지가 않았기 때문인 듯.

아는 만큼 이해할 수 있는 책이기 때문에 IT 인프라에 대한 지식이 갖춰진 사람은 가볍게 읽을 수 있을 듯.

C# 6.0 완벽 가이드/ 고급 스레드 기법

동기화 개요

  • 동기화(synchronization)란 동시에 실행되는 작업들이 예측 가능한 최종 결과를 내도록 그 작동을 조율하는 것을 말한다. 동기화는 여러 스레드가 같은 자료에 접근할 때 특히나 중요하다. 그런 코드를 작성할 때는 뭔가를 빼먹거나 잘못 구현하기가 놀랄만큼 쉽다
  • 가장 간단하고 유용한 동기화 도구는 14장에서 설명한 연속(continuation) 기능과 작업 조합기(task combinator)일 것이다. 동시적 프로그램을 다수의 비동기 연산들이 연속 작업 객체들과 조합기들로 연결된 구조로 만들면 잠금과 신호 전달의 필요성이 줄어든다.
    • 그렇지만 저수준 수단들을 동원해야 하는 경우도 여전히 존재한다.
  • 동기화 수단들은 크게 다음 세 부류로 나뉜다.
    • 독점 잠금
        • 독점 잠금(exclusive locking)은 한 번에 단 하나의 스레드만 어떠한 활동을 수행하거나 코드의 한 부분을 실행하게 만드는 수단이다. 독점 잠금은 여러 스레드가 서로 간섭하지 않고 공유 상태에 접근해서 상태를 변경할 수 있게 하는데 주로 쓰인다.
      • C#의 독점 잠금 수단으로는 lock과 Mutex, SpinLock이 있다.
    • 비독점 잠금
      • 비독점 잠금(nonexclusive locking)은 동시성을 제한하는 수단이다. 비독점 잠금 수단으로는 Semaphore(Slim)과 ReaderWriterLock(Slim)이 있다.
    • 신호 전달
      • 신호 전달(signaling)은 다른 스레드로부터 하나 또는 여러 개의 통지를 받을 때까지 한 스레드의 실행을 차단하는 수단이다.
      • 신호 전달 수단으로는 ManualResetEvents(Slim), AutoResetEvent, CountdownEvent, Barrier가 있다. 처음 셋을 이벤트 대기 핸들(event wait handles)이라고 부른다.
  • 비차단 동기화(nonblocking synchronization) 수단들을 이용해서 잠금 없이 공유 상태에 대한 동시적 연산을 수행하는 것도 가능하다.(까다롭긴 하지만)
    • 비차단 동기화 수단으로는 THread.MemoryBarrier, Thread.VolatileRead, Thread.VolatileWrite.volatile 키워드, Interlocked 클래스가 있다.

Continue reading

백종원의 장사 이야기

현재 가장 잘 나가는 요식업계의 큰 손 백종원씨의 장사 이야기. 그간의 컨설팅 경험을 엮어냈다고 한다.

성공한 사업가의 성공한 후 이야기이긴 하지만, 성공과 실패의 사이클을 두루 경험한 사람의 이야기인지라 새겨 들을만한 내용도 많고, 경험자만이 아는 이야기도 담겨 있어서 좋다. –나는 음식 장사를 할 생각은 없어서 나에게는 큰 도움은 안 되겠지만

흥미로운 점은 역시나 어느 분야든 성공한 사람에게는 통하는 부분이 있다는 것 –안나 카레니나의 법칙은 유효하다– 인내심을 강조하는 것이 참 마음에 닿았다. –다만 백종원씨처럼 몇년간 발생하는 적자를 감당할 수 있는 사람이 얼마나 있을지는 모르겠다.

스케일

개인적으로 좋아하는 복잡성을 주제로 한 책. 제목에서 짐작할 수 있듯이, 그중에서도 크기와 관련된 복잡성에 대한 이야기를 담고 있다.

생명체, 도시, 기업 등의 크기에 따른 대사율 변화와 망의 유사성에 대해 물리적인 수준에서 이해하고 그 규칙성을 — 1/4, 3/4 스케일링– 논하고 있는데, 기존에 접했던 복잡성 관련 책들에서는 다뤄지지 않았던 내용들이라 흥미롭게 읽었다. 차후에 별도로 공부를 해둬야겠다는 생각을 했음.  –복잡계에 나타나는 자기조직화, 자기유사성-프랙탈 구조 등은 결국 엔트로피-에너지와 물리적 제약을 이해하면 자연스럽게 따라오는 내용인 것 같다.

다만 도시와 기업의 차이에 대한 부분은 견해가 다른데, 도시가 초선형 스케일링이 가능하고 기업이 저선형 스케일링하는 것은 저자가 이야기하는 혁신의 문제가 아니라 대사 방식 –에너지를 흡수하고 엔트로피를 배출하는– 의 차이라고 생각 함. 도시는 구성원들의 세금을 통해 내부적으로 에너지를 확보할 수 있는 반면, 기업은 외부에서 에너지를 확보해서 내부 구성원들에 나눠줘야 하는 대사 방식의 차이로 도시는 대게 오래가는 반면, 기업은 대개 오래 못가는 것이라 생각 함. 도시도 인구가 줄면 망하는 도시는 얼마든지 나오게 마련인데, 저자가 미국에 살아서 일본과 같은 고령화 사회에서 나타나는 현상을 몰랐던게 아닐까 싶다.

개인적으로 배운게 많았고, 복잡성/복잡계는 우리가 실제적으로 부딪히는 현실 세계를 –소립자의 세계는 현실적으로 느끼기 어려운 영역이니– 잘 설명해 주는 분야이기 때문에 내용적으로는 추천할 만하지만, 복잡계 관련한 내용을 좀 접한 나도 따라가지 못한 부분들 –복잡계 자체보다는 물리학이나 생물학에 대한 내용– 좀 있어서 쉬운 책은 아니니 그것만 고려하면 될 듯.

C# 6.0 완벽 가이드/ 보안

  • .NET에서 권한(permission)은 운영체제가 강제하는 것과는 독립적인 하나의 보안 계층을 제공한다. .NET Framework에서 권한의 주된 용도는 다음 두 가지 이다.
    • 모래상자 적용
      • 부분적으로 신뢰된 .NET 어셈블리가 수행할 수 있는 연산 종류를 제한한다.
    • 권한 부여(인가)
      • 누가 무엇을 할 수 있는지를 제한한다.
  • .NET의 암, 복호화(cryptography) 기능은 고가 자료의 저장 및 교환, 정보 유출 방지, 메시지 위변조 검출, 패스워드 저장을 위한 단방향 해시 생성, 디지털 서명 생성 등에 쓰인다.

권한

  • .NET Framework는 권한 기능을 모래상자와 권한 부여(authorization; 인가)에 사용한다.
    • .NET Framework에서 하나의 권한은 어떤 코드의 실행을 조건에 따라 금지하는 일종의 관문으로 작용한다.
    • 모래상자 적용에는 코드 접근 권한들이 쓰이고, 권한 부여에는 신원(identity) 권한들과 역할(role) 권한들이 쓰인다.
  • 이들은 모두 비슷한 모형을 따르지만 사용해보면 그 느낌이 상당히 다르다. 부분적인 이유는 관점이 정반대라는 것이다.
    • 일반적으로 코드 접근 보안에서는 독자의 코드가 신뢰받지 않는 쪽, 즉 불신의 대상(untrusted party)이다.
    • 그러나 신원 및 역할 보안에서는 독자의 코드가 다른 어떤 코드를 신뢰하지 않는 쪽, 즉 불신의 주체(unstrustig party)이다.
    • 대부분의 경우 코드 접근 보안은 CLR이나 호스팅 환경(ASP.NET이나 Internet Explorer)이 독자의 코드에 강제하지만, 권한 부여 관련 보안은 독자의 코드가 다른 어떤 단위에 강제한다(독자의 코드에 함부로 접근하지 못하도록)
  • 권한이 제한된 환경에서 실행될 어셈블리를 작성하는 응용 프로그램 개발자라면 누구나 코드 접근 보안(code access security, CAS)을 숙지할 필요가 있다.
    • 예컨대 어떤 구성요소 라이브러리를 작성해서 판매하는 경우, 고객이 독자의 라이브러리를 SQL Server CLR 호스트 같은 모래상자 안의 환경에서 호출할 수도 있음을 간과한다면 좋은 평가를 받기 어려울 것이다.
  • 다른 어셈블리들을 모래상자 안에서 실행하는 호스팅 환경을 직접 만들 때도 CAS를 숙지할 필요가 있다.
    • 예컨대 서드파티 개발자들이 작성한 플러그인 구성요소를 실행할 수 있는 응용 프로그램을 만든다고 하자. 그런 플러그인들을 권한이 제한된 응용 프로그램 도메인에서 실행하면 잘못된 플러그인 때문에 응용 프로그램이 불안정해지거나 보안이 손상될 확률이 줄어든다.
  • 신원/역할 보안은 주로 중간층(middle-tier) 서버나 웹 응용 프로그램 서버를 작성할 떄 쓰인다. 그런 경우 흔히 일단의 역할들을 정해 두고, 서버가 노출하는 메서드마다 그 메서드를 어떤 역할의 구성원들이 호출할 수 있는지 설정한다.

Continue reading

C# 6.0 완벽 가이드/ 동적 프로그래밍

DLR(동적 언어 런타임)

    • C#은 DLR(dynamic language runtime; 동적 언어 런타임)에 의존해서 동적 바인딩(dynamic binding)을 수행한다.
    • 이름이 주는 느낌과는 달리 DLR은 CLR의 동적 버전이 아니다. DLR은 System.Xml.Dll 같은 다른 모든 라이브러리와 마찬가지로 그냥 CLR 위에 놓인 하나의 라이브러리이다. DLR의 주된 역할은 정적 형식 언어와 동적 형식 언어 모두에서 동적 프로그래밍의 통합을 위한 실행시점 서비스들을 제공하는 것이다.
      • DLR 덕분에 C#이나 VB, IronPython, IronRuby 같은 여러 언어는 동적으로 함수를 호출할 때 동일한 규약을 따른다.
      • 결과적으로 이 언어들은 같은 라이브러리를 공유할 수 있으며, 다른 언어로 작성된 코드를 호출할 수 있다.
    • 또한 .NET에서 새로운 동적 언어를 작성하기가 비교적 쉬운 것도 DLR 덕분이다. 동적 언어를 작성할 때 IR 코드를 직접 산출하는 코드를 작성하는 대신, 표현식 트리를 다루는 코드를 작성하면 된다.
    • 더 나아가서 DLR은 모든 소비자가 호출 사이트 캐싱(call-site caching)의 혜택을 받게 한다. 호출 사이트 캐싱은 동적 바인딩 과정에서 잠재적으로 비싼 멤버 환원 결정을 되풀이 하지 않기 위해 DLR이 사용하는 하나의 최적화 기법이다.
  • DLR은 .NET Framework 4.0에서 처음으로 .NET Framework 자체에 포함되었다. 그 전에는 Codeplex에서 따로 내려받아야 하는 라이브러리였다. 지금도 Codeplex 사이트에는 동적 언어 작성자에 유용한 몇 가지 추가 자원이 있다.

Continue reading

C# 6.0 완벽 가이드/ 반영과 메타자료

  • 앞장에서 보았듯이, C# 프로그램 소스 코드를 컴파일하면 어셈블리가 만들어진다. 어셈블리는 컴파일된 코드와 메타자료(metadata) 그리고 기타 자원들로 구성된다. 컴파일된 코드와 메타자료를 실행시점에서 조사하는 것을 가리켜 반영(reflection)이라고 한다.
  • 어셈블리 안에 담긴 컴파일된 코드에는 원 소스 코드의 내용이 거의 다 들어 있다. 지역변수 이름이나 주석, 전처리기 지시문 등의 일부 정보는 컴파일 과정에서 사리지지만 그 나머지의 상당 부분은 반영 기능을 이용해서 접근할 수 있다.
    • 실제로 반영 기능을 이용해서 역컴파일러(decompiler)를 작성하는 것도 가능하다.
  • .NET Framework가 제공하는 그리고 C#을 통해서 노출되는 여러 서비스(동적 바인딩, 직렬화, 자료 바인딩, Remoting 등)는 메타자료가 있어야 작동한다.
    • 독자가 작성하는 프로그램 역시 메타자료를 활용할 수 있으며 심지어는 커스텀 특성을 이용해서 메타자료에 새로운 정보를 추가할 수도 있다.
    • 반영 API는 System.Reflection 이름공간에 들어 있다. System.Reflection.Emit 이름공간에 있는 클래스들을 이용하면 새 메타자료와 실행 가능한 IL(Intermediate Language; 중간 언어) 코드를 동적으로 생성하는 것도 가능하다.
  • 이번 장에서 뭔가를 ‘동적으로’ 수행한다는 것은 형식 안전성이 오직 실행시점에서만 강제되는 어떤 작업을 반영 긴으을 이용해서 수행하는 것을 뜻한다.
    • 구체적인 메커니즘과 기능성은 다르지만 원칙적으로 이는 C#의 dynamic 키워드를 통한 동적 바인딩과 비슷하다.
    • 둘을 비교하자면 동적 바인딩이 반영 기능보다 훨씬 사용하기 쉽다. 그리고 동적 바인딩은 동적 언어 상호운용성을 위해 DLR(Dynamic Language Runtime)을 활용한다.
    • 반영은 사용하기가 비교적 번거롭고 오직 CLR만 고려한다. 그러나 CLR로 할 수 있는 것의 관점에서 본다면 좀 더 유연하다.
    • 예컨대 반영 기능을 이용해서 형식들과 멤버들의 목록을 얻을 수 있고, 형식의 이름을 문자열로 지정해서 그 인스턴스를 생성할 수 있으며, 즉석에서 어셈블리를 구축할 수 있다.

Continue reading

C# 6.0 완벽 가이드/ 어셈블리

  • 어셈블리(Assembly)는 .NET의 기본 배치(deployment) 단위이다. 모든 형식은 어셈블리 안에 담긴다. 하나의 어셈블리는 컴파일된 형식과 해당 IL(Intermediate Language) 코드, 실행시점 자원, 그리고 보조 정보(버전 관리, 보안, 다른 어셈블리 참조 등을 위한)로 구성된다.
    • 어셈블리는 또한 형식 결정과 보안 권한 부여의 경계선을 정의하는 역할도 한다.
  • 보통의 경우 하나의 어셈블리는 하나의 Windows PE(Portable Executable) 파일인데, 응용 프로그램 실행 파일(executable)에 해당하는 어셈블리 파일의 확장자는 .exe이고 재사용 가능한 라이브러리의 확장자는 .dll이다.
    • 단 WinRT 라이브러리는 확장자가 .winmd이다. WinRT 라이브러리 파일은 .dll과 비슷하나, 메타자료만 있고 IL 코드가 없다는 점이 다르다.
  • 이번 장에 등장하는 형식들은 대부분 다음 이름공간들에 정의되어 있다.
    • System.Reflection
    • System.Resources
    • System.Globalization

어셈블리의 구성

  • 어셈블리를 구성하는 요소는 다음 네 가지이다.
    • 어셈블리 매니페스트
      • 어셈블리 매니페스트(Manifest)는 .NET 런타임에 관한 정보를 제공한다. 예컨대 어셈블리의 이름, 버전, 어셈블리가 요청한 권한들, 그리고 어셈블리가 참조하는 다른 어셈블리들의 목록이 어셈블리 매니페스트에 들어 있다.
    • 응용 프로그램 매니페스트
      • 응용 프로그램 매니페스트는 운영체제에 필요한 정보를 제공한다. 예컨대 어셈블리를 배치하는 방법이나 관리자로의 권한 상승이 필요한지의 여부 등이 응용 프로그램 매니페스트에 들어 있다.
    • 컴파일된 형식
      • 어셈블리가 정의하는 형식들을 컴파일해서 나온 IL 코드와 형식들의 메타자료(metadata)
    • 자원
      • 이미지나 현지화용 텍스트 등의 기타 자료
  • 이들 중 필수인 것은 어셈블리 매니페스트 뿐이다. 그러나 WinRT 참조 어셈블리가 아닌 한 어셈블리에는 거의 항상 컴파일된 형식들이 들어 있다.
  • 실행 파일 어셈블리와 라이브러리 어셈블리의 구조는 거의 같다. 주된 차이는 실행 파일 어셈블리에는 진입점(entry point)이 정의되어 있다는 점이다.

Continue reading

모두 거짓말을 한다

각종 사회 현상에 대해 일반적으로 알지 못했던 혹은 잘못 알고 있었던 여러 사안들에 대해 데이터 분석을 이용하여 ‘실제는 이렇다’ 라고 이야기하는 책.

구글 트렌드와 페이스북, PornHub의 같은 빅 데이터를 이용하여 사람들이 흥미로워 할만한 여러 이야기들을 잘 잡아내고 있다. 가볍게 읽어볼만한 내용인 듯.

기존에 측정하지 못했던 데이터 –측정이 어려웠는데 측정이 가능해진 것들 또는 사람들이 솔직하게 대답하지 않은 민감한 이슈들에 대한 데이터들 등– 를 바탕으로 현실에 대한 올바른 이해를 얻는 것은 좋으나, 빅데이터라는 개념이 뜨기 전에도 샘플링을 바탕으로 데이터 분석은 있었고 –책에서는 빅데이터의 장점이 부분별 스케일링이 가능하다는 것으로 이야기 함– , 수 많은 데이터 중에 올바른 데이터를 보는 것이 중요하며, 수치로 드러나는 데이터에만 종속되면 안되는 –세이버메트릭스가 MLB의 주류가 되었지만, 숫자로는 드러나지 않는 정보를 얻기 위해 스카우팅은 여전히 중요하다– 것 또한 책에서 강조되고 있으니, 빅데이터가 모든 것을 해결해 줄 것이라는 맹신은 하지 않는 것이 좋다. –같은 맥락에서 딥러닝 또한 마찬가지.