ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java Multithreading [4] - 성능 최적화의 두 관점 - 지연 시간
    Java/Multi Threading 기초 2022. 8. 29. 08:46

    Java Multithreading

    멀티스레딩의 개념과 Java에서의 활용법을 공부하고 정리하는 시리즈입니다.

    4.1. 성능 최적화의 두 관점 - 지연 시간


    프로그램의 성능을 최적화한다는 것은 구체적으로 무엇을 말하는 것일까요?
    프로그램의 처리 속도를 높이는 것이 될 수도 있고, 통신의 레이턴시를 낮추는 것일 수도 있고, 정확한 응답값을 반환하는 것일 수도 있고, 정확한 조건에 동작하는 것일 수도 있고... 사실 '성능 최적화'라고만 말한다면 상황에 따라 수많은 정의가 적용될 수 있을 것 같습니다.

    하지만 이번 포스팅에서는 성능을 관측하는 데에 대표적으로 쓰이는 두 가지 지표만을 공부해보려고 합니다.
    첫번째는 지연 시간(latency), 두번째는 처리량(Throughput)입니다.

    멀티스레딩 프로그래밍에서 지연 시간을 줄이는 방법은 간단합니다. 작업해야 할 작업량을 스레드의 개수로 나누어 병렬로 진행하는 것입니다. 사용자가 요청하고 응답을 받기까지 T의 시간이 걸리는(지연시간이 T인) 프로그램이었다면, 멀티스레드 프로그래밍을 적용하고 나면 지연시간을 T/N로 줄일 수 있습니다.

    물론 이것은 이상적인 예시입니다. T가 소요되는 작업을 N으로 나누려면, 작업을 나누어 진행하는 것이 가능한지를 먼저 생각해보아야 합니다. 작업 단위를 나눌 수 없는 작업이라면 N개의 스레드가 투입되어도 단지 순차적으로 실행될 뿐 병렬로 처리할 수는 없을 테니까요.

    또한 작업을 나누고 결과를 다시 취합하는 데에 지나치게 오래 걸리는 작업이라면, 오히려 나누지 않는 것이 더 나은 결과를 보일 수도 있습니다.

    또한 작업을 지나치게 덜 나누거나, 지나치게 많이 나누는 경우에도 별다른 성능 향상을 보이지 않을 수 있습니다. 우리가 원하는 이상적인 경우는 N개의 스레드가 각기 동시에 동작해서 / 쉬지 않고 수행된 다음 / 거의 동일한 시간에 작업을 마무리 하는 것입니다. 달리 말하면 작업이 동작하는 중에는 할당된 모든 스레드가 가능한 한 Runnable 상태를 유지해야 합니다. 더 쉽게 말하면 모든 작업이 병렬로 진행되어야 한다는 것이죠.
    그러기 위해서는 몇 개의 하위 작업으로 나눠야 할까요? 몇 개의 N으로 나누었을 때 가장 최적의 성능을 확보할 수 있을까요?

    보통은 작업을 수행하는 머신의 코어 개수와 비슷해야 합니다. 이전 포스팅들에서 설명했던 적이 있는 것 같은데요. 완전히 병렬적으로 실행되는 건 별도의 코어에서 각각 작업을 진행할 때에만 가능합니다. 코어를 확보할 수 있는 상황이라면(특별히 중요한 프로세스가 따로 없는 상황이라면), 저희가 의도한 대로 최적의 성능을 보여줄 수 있겠죠.

    하지만 계속 반복해서 말하고 있듯이, 이것들은 고려해야 하는 대상일 뿐이지 반드시 원하는 대로 결과를 보장하는 것들은 아닙니다. 어떤 프로세스들이 실행되고 있는 환경인지도 알 수가 없고, 운영체제의 스케줄링에 관여할 수도 없고, IO블로킹이 있을 수도 있고, 그 밖에도 수많은 변인이 있기 때문입니다.

    그럼에도 어떤 작업을 여러개의 하위 작업으로 나누어 병렬적으로 처리 할 때에 지연시간을 최적화 하고 싶다면 위의 내용들을 고려해야 합니다.
    작업을 나눌 수 있는지 확인하고, 싱글 스레드의 실행 성능과 비교하여 오버헤드를 측정하고, 나눌 작업의 수를 고민해야 합니다.

    지금까지 멀티스레드 프로그래밍에서 지연시간을 최적화 하기 위한 몇 가지 방법을 정리해 보았습니다.
    다음 글에서 뵈어요! 😃

    댓글

Designed by Tistory.