Skip to content

Chapter 12. 동시 성능 기법 #12

@HaeUlNam

Description

@HaeUlNam

정리

  • 무어의 법칙: 칩 하나에 꽂을 수 있는 트랜지스터 개수가 매년 2배 증가. 50년 정도동안은 유효했음.
  • 암달의 법칙
    • T(N) = S + (1/N) * (T - S)
    • S: 순차 실행 파트
    • T: 총 태스크 소요 시간
    • N: 프로세서 개수
    • 동시 작업은 T - S이고, N 개 프로세스에 태스크를 고루 분배한다고 가정하면 전체 태스크 소요 시간은 다음과 같다.
    • 낯간지러운 병렬: 병렬 태스크나 다른 순차 태스크 간에 소통할 필요가 전혀 없을 경우 이론적으로 속도는 무한히 높일 수 있다.
  • 자바 동시성
    • volatile 키워드
      • Main memory로부터 최신 값을 가져오도록 한다.
      • Thread Safety Case
        • 오직 하나의 Thread만 write하는 경우
        • 여러 thread가 write하지만 Atomic하게 write하는 경우
      • Non-Thread Safety case
        • non-atomic/composite operation
        • e.g. 증가/감소 와 같은 operation. 증가/감소는 3가지 operation(Read variable, Update, Writing the updated back to memory)으로 이루어져있기 때문에 이 짧은 시간동안 race condition 발생 가능
      • https://www.baeldung.com/java-volatile-variables-thread-safety
  • JMM(Java Memory Model)의 이해
  • CAS(Compare-And-Swap): non-blocking algorithms for concurrent environments. 단일 연산으로 Read, Update, Writing the updated back to memory를 처리한다.
    • Non-blocking algorithm: 특정 스레드에서 작업이 실패하거나 또는 대기 상태에 들어가는 경우에, 다른 어떤 스레드라도 그로인해 실패하거나 대기 상태에 들어가지 않는 알고리즘을 Non-Blocking 알고리즘이라고 한다. 또한 각 작업 단계마다 일부 스레드는 항상 작업을 진행할 수 있는 경우 Lock-Free 알고리즘이라고 한다.
    • JVM에서의 CAS 지원은 Java 5.0에서부터 시작되었고, CAS 연산을 직접 지원하는 하드웨어에서는 해당 부분을 기계어로 변환.
    • https://effectivesquid.tistory.com/entry/Lock-Free-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98Non-Blocking-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98
  • Intrinsic lock vs spin lock
    • Intrinsic lock: 유저 코드에서 OS를 호출함으로써 작동. OS를 이용해 스레드가 따로 신호를 줄 떄까지 무한정 기다리게 만드는 것
    • Spin lock: 블로킹된 스레드를 CPU에 활성 상태로 놔두고, 아무 일도 시키지 않은 채 계속 재시도(CPU cycle 소모)
  • 동시 라이브러리
    • java.util.concurrent.locks.Lock interface
      • lock(): 기존 방식대로 락을 획득하고 락을 사용할 수 있을 때까지 블로킹
      • tryLock(): 락을 획득하려고 시도하고, true/false를 return. 타임아웃 설정도 할 수 있음.
      • ReentrantLock: Lock의 구현체
      • ReentrantReadWriteLock의 ReadLock과 WriteLock을 사용하면, 여러 스레드가 읽기 작업을 하는 도중에는 다른 읽기 스레드를 블로킹하지 않게 할 수 있다. 블로킹은 쓰기만 일어남. 읽기가 많이 일어나는 Application에서 좋다.
    • Semaphore: ‘최대 O개 객체까지만 액세스를 허용’과 같이 여러 리소스의 액세스를 허용하는 독특한 기술을 제공
      • acquire: 사용 가능한 퍼밋 수를 하나씩 줄임. 쓸 수 있는 퍼밋이 하나도 없을 경우 blocking
      • release: 퍼밋을 반납하고 대기 중인 스레드 중에서 하나에게 해제한 퍼킷을 전달
    • CountDownLatch: Count를 셋팅하고, 각 스레드가 countdown()을 호출할 때마다 카운트 값을 1 감소하고, 0에 이르면 Latch가 열린다.
    • ForkJoinPool
      • 하위 분할 테스크를 효율적으로 처리 가능
      • 작업 빼앗기 알고리즘

질문

  • Q. 왜 약한 메모리 모델이 강한 메모리 모델보다 이식성이 높은 건가? 최근 CPU 아키텍처들이 약한 메모리 모델이라서?
  • Q. CountDownLatch는 현재 단계의 모든 일을 처리하고 다음 단계로 넘어가야 할 때 사용? 실제 이런 사례가 있는 게 있을까? 써본적이 없어서...
  • Q. 책에서는 경합 중인 리소스가 극히 짧은 시간동안만 사용할 경우 Intrinsic lock 방식은 막대한 오버헤드를 유발할 수 있다고 한다. 이것에 공감하지만, 경합 중인 리소스를 극히 짧은 시간동안 사용하는걸 어떻게 알지?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions