devlog of ShinJe Kim

[TIL] 2019-09-05

|

Today I Learned

  • 암달의 법칙(Amdal’s Law): 프로그램은 병렬처리가 가능한 부분과 불가능한 순차적인 부분으로 구성되므로 프로세서를 아무리 병렬화 시켜도 더 이상 성능이 향상되지 않는 한계가 존재한다는 법칙. 암달의 저주라고도 불린다.
  • 구스타프슨의 법칙(Gustafson’s Law): 컴퓨터 과학에서 대용량 데이터 처리를 효과적으로 병렬화할 수 있다는 법칙이다. 즉, 계산 과학에서 커다란 문제는 병렬화를 효과적으로 하여 처리할 수 있다는 개념이다.
  • 동기/비동기 vs 블록/논블록
    • 동기/비동기는 OS의 관점
    • 블록/논블록은 추상적인 event의 관점
    • read 연산을 수행한다고 가정해보자.
      • 동기: 기존의 실행 흐름에서 read 연산으로 흐름이 바뀜. read 연산이 끝날때까지 제어는 read 연산에 있음. read 연산이 끝나고서야 기존의 제어가 실행됨.
      • 비동기: 기존의 실행 흐름을 그대로 유지하면서 또 하나의 실행 흐름(read)이 병행되는 것.
      • 블록: 버퍼에 read 연산이 들어오기전까지는 CPU를 대기 상태로 유지하는 것
      • 논블록: 버퍼에서 실행해야 하는 것이 없어도 대기 상태로 유지하지 않는 것
  • 만약 직렬화를 하고 싶으면? 리플렉션을 이용하여 필드와 필드의 값이 뭔지를 알아내야 한다.
  • 리플렉션(Reflection)이란?
    • 컴퓨터과학에서의 리플렉션이란 프로그램이 실행중에 자신의 구조와 동작을 검사하고, 조사하고, 수정하는 것.
    • 리플렉션은 프로그래머가 데이터를 보여주고, 다른 포맷의 데이터를 처리하고, 통신을 위해 직렬화를 수행하고, bundling을 하기 위해 일반 소프트웨어 라이브러리를 만들도록 도와줌.
    • 자바 리플렉션을 사용하면 구체적인 클래스 타입을 알지 못해도 해당 클래스의 메소드, 타입, 변수 등에 접근할 수 있음.
    • 하지만 리플렉션을 사용하는 것에는 문제점이 있다. 아래는 이펙티브 자바의 “리플렉션보다는 인터페이스를 사용하라” 챕터에서 발췌하였다.
      • 컴파일타임 타입 검사가 주는 이점을 하나도 누릴 수 없다: 프로그램이 리플렉션 기능을 써서 존재하지 않는 혹은 접근할 수 없는 메서드를 호출하려 시도하면(주의해서 대비 코드를 작성해두지 않았다면) 런타임 오류가 발생한다.
      • 리플렉션을 이용하면 코드가 지저분하고 장황해진다
      • 성능이 떨어진다: 리플렉션을 통한 메서드 호출은 일반 메서드 호출보다 훨씬 느리다.
      • 따라서 리플렉션은 아주 제한된 형태로만 사용해야 그 단점을 피하고 이점만 취할 수 있다.
      • 컴파일 타임에 이용할 수 없는 클래스를 사용해야만 하는 프로그램은 비록 컴파일 타임이라도 적절한 인터페이스나 상위 클래스를 이용할 수는 있을 것이다. 이런 경우라면 리플렉션은 인스턴스 생성에만 쓰고, 이렇게 만든 인스턴스는 인터페이스나 상위 클래스로 참조해 사용하자.
  • 프로그램 프로파일링: 프로그램의 성능 분석을 의미한다. 프로그램의 시간 복잡도 및 메모리 등이 얼마나 효율적으로 관리/사용되는지 분석하는 것.
  • 자바의 익명 클래스: 클래스의 선언과 객체의 생성을 동시에 한다. 한 번만 사용될 수 있으며 오직 하나의 객체만을 생성할 수 있는 일회용 클래스이다.
  • 지연 초기화(lazy initialization): 모든 객체를 한 번에 생성하는 것이 아니라, 실제로 처음 쓰이는 시점에 생성하겠다는 것. 자바에서는 이를 직접 구현해야만 함. 이 떄 스레드 안정성에 문제가 생김.
  • 스레드 안전(Thread safe)이란? 멀티 스레드 프로그래밍에서 어떠한 함수나 변수 혹은 객체가 여러 스레드로부터 동시에 접근이 이루어져도 프로그램의 실행에 문제가 없는 것을 의미함. 보다 엄밀하게는 하나의 함수가 한 스레드로부터 호출되어 실행중일 때 다른 스레드가 그 함수를 호출하여 동시에 실행되더라도 각 스레드에서의 함수의 수행 결과가 올바로 나오는 것을 의미함. 코틀린의 오브젝트 선언이 이를 안전하게 실행할 수 있도록 해줌.
  • 스레드 안전을 지키기 위한 방법
    • Re-entrancy: 어떤 함수가 한 스레드에 의해 호출되어 실행중일 때, 다른스레드가 그 함수를 호출하더라도 그 결과가 각각에게 올바로 주어져야 함.
    • Thread-local storage: 공유 자원의 사용을 최대한 줄여 각각의 스레드에서만 접근 가능한 저장소들을 사용함으로써 동시 접근을 막음. 이 방식은 동기화 방법과 관련되어 있으며 공유상태를 피할 수 없을 때 사용함.
    • Mutual exclusion: 공유 자원을 꼭 사용해야 할 경우 해당 자원의 접근을 세마포어 등의 락으로 통제함.
    • Atomic operations: 공유 자원에 접근할 떄 원자 연산을 이용하거나 ‘원자적’으로 정의된 접근 방법을 사용함으로써 상호 배제를 구현할 수 있음.

참고 자료

Comments