[EXT-041][실무] 작업 스레드 수를 측정으로 정하기 > IT 기술 공유

본문 바로가기

사이트 내 전체검색

뒤로가기 IT 기술 공유

[EXT-041][실무] 작업 스레드 수를 측정으로 정하기

페이지 정보

작성자 기술팀장 작성일 26-09-09 07:36 조회 8 댓글 0

본문

[이번 수업]
작업자 풀은 크게 잡는다고 항상 빨라지지 않습니다. Node.js가 알려 주는 병렬 처리량을 출발점으로 삼고, 같은 계산을 여러 Worker 수로 실행해 시간을 비교합니다.

[선수지식]
EXT-039의 Worker와 EXT-040의 작업자 풀을 이해해야 합니다. 현재 지원 Node.js를 준비하세요.

[학습목표]
1. 실행 환경이 권장하는 병렬 처리량을 확인한다.
2. 같은 총 작업량을 여러 Worker 수로 나누어 측정한다.
3. 반복 측정으로 풀 크기를 고른다.

[핵심개념]
availableParallelism()은 프로그램이 쓸 병렬 처리량의 추정치를 1 이상의 정수로 반환합니다. 공식 문서는 이 목적에 os.cpus().length를 쓰지 말라고 안내합니다. 다만 이 값이 곧 최적 Worker 수는 아닙니다. 스레드 생성, 메시지 전달, 메모리 경쟁에도 비용이 듭니다. performance.now()는 프로세스 시작을 기준으로 한 고해상도 밀리초 시각입니다. 같은 입력과 환경에서 여러 번 측정하고 처리량뿐 아니라 응답 지연과 오류도 함께 보세요.

[따라하기]
아래 내용을 size-check.mjs로 저장하세요. 총 반복 횟수는 같고 Worker 수만 바뀝니다.

```js
import { availableParallelism } from 'node:os';
import { performance } from 'node:perf_hooks';
import { Worker, isMainThread, parentPort, workerData } from 'node:worker_threads';

if (!isMainThread) {
  let checksum = 0;
  for (let i = 0; i < workerData; i++)
    checksum = (checksum + i) % 1_000_003;
  parentPort.postMessage(checksum);
} else {
  const available = availableParallelism();
  const candidates = [1, Math.min(2, available), Math.min(4, available)]
    .filter((value, index, list) => list.indexOf(value) === index);

  async function runOne(iterations) {
    const worker = new Worker(new URL(import.meta.url), { workerData: iterations });
    try {
      return await new Promise((resolve, reject) => {
        worker.once('message', resolve);
        worker.once('error', reject);
      });
    } finally {
      await worker.terminate();
    }
  }

  console.log(`available=${available}`);
  for (const size of candidates) {
    const each = Math.ceil(20_000_000 / size);
    const started = performance.now();
    await Promise.all(Array.from({ length: size }, () => runOne(each)));
    const elapsed = Math.round(performance.now() - started);
    console.log(`workers=${size} elapsedMs=${elapsed}`);
  }
}
```

Windows·macOS·Linux 모두 `node size-check.mjs`를 실행합니다. 값은 기기마다 다르지만 available은 1 이상이고 각 후보의 시간이 표시됩니다.

```text
available=8
workers=1 elapsedMs=220
workers=2 elapsedMs=135
workers=4 elapsedMs=110
```

[흔한 실수]
한 번 가장 빠른 값을 정답으로 확정하거나 서로 다른 총 작업량을 비교하지 마세요. 절전 상태와 다른 프로그램의 부하도 결과를 흔듭니다. Worker 시작 비용 포함 여부도 기록하세요.

[보안 주의]
입력 크기와 Worker 상한을 고정해 자원 고갈을 막습니다. 운영 서버에서 갑자기 부하 시험을 하지 말고 본인 소유의 로컬·격리 환경에서 시작하세요. 로그에는 원문이나 비밀값 대신 작업 ID, 시간, 성공 여부만 남깁니다.

[직접 해볼 과제]
스크립트를 다섯 번 실행해 후보별 중앙값을 기록하세요. 반복 횟수를 절반으로 줄여 시작 비용의 영향을 비교하고, 실제 CPU 작업으로 바꿔 처리량과 지연 시간을 함께 표로 만드세요.

[확인문제]
1. os.cpus().length보다 availableParallelism()이 알맞은 이유는 무엇일까요?
2. Worker 수를 늘려도 실행 시간이 줄지 않을 수 있는 이유는 무엇일까요?
3. 풀 크기를 공정하게 비교하려면 어떤 조건을 같게 해야 할까요?

[다음 학습]
다음에는 작업의 시작·종료·실패를 AsyncResource로 연결해 비동기 진단 정보를 올바르게 남깁니다.

[공식 참고 자료]
Node.js os.availableParallelism()
https://nodejs.org/api/os.html#osavailableparallelism
Node.js performance.now()
https://nodejs.org/api/perf_hooks.html#performancenow
Node.js Worker threads
https://nodejs.org/api/worker_threads.html

댓글목록 0

등록된 댓글이 없습니다.

Copyright © 소유하신 도메인. All rights reserved.

사이트 정보

회사명 : 회사명 / 대표 : 대표자명
주소 : OO도 OO시 OO구 OO동 123-45
사업자 등록번호 : 123-45-67890
전화 : 02-123-4567 팩스 : 02-123-4568
통신판매업신고번호 : 제 OO구 - 123호
개인정보관리책임자 : 정보책임자명

PC 버전으로 보기