Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[engine] 로그 개수에 맞는 쓰레드 생성 #743

Merged
merged 1 commit into from
Oct 2, 2024
Merged

[engine] 로그 개수에 맞는 쓰레드 생성 #743

merged 1 commit into from
Oct 2, 2024

Conversation

BeA-Pro
Copy link
Contributor

@BeA-Pro BeA-Pro commented Oct 1, 2024

Related issue

Result

이전에 Worker를 사용하여 병렬적으로 로그를 받아오는 기능을 구현했습니다.
이 과정에서 항상 컴퓨터 코어 수 - 1개의 쓰레드를 생성하여 로그를 받아왔는데 멘토님께서 이는 메모리를 과하게 사용하는 매우 비효율적인 작업이라고 지적해주셨습니다.

따라서 로그 수에 따른 적절한 쓰레드 개수를 찾기 위해 사용하는 소요되는 메모리 양과 걸리는 시간을 평가하였습니다.

setInterval(() => {
    const memoryUsage = process.memoryUsage();
    const rssUsage = memoryUsage.rss / 1024 / 1024; // RSS 메모리(MB)로 변환
    maxMemoryUsage = Math.max(maxMemoryUsage, rssUsage);
}, 10);

소요되는 메모리의 양을 정확히 구할 수는 없기 때문에 위와 같이 setInterval 함수를 사용하여 코드가 실행되는 동안 메모리 사용량을 10ms마다 기록하여 최댓값을 구하였습니다.

const startMemoryUsage = process.memoryUsage().rss / 1024 / 1024; // 단위 MB
// setInterval 실행
// 로그 받아오는 코드 실행
const memoryIncrease = maxMemoryUsedDuringTask - startMemoryUsage; // maxMemoryUsedDuringTask에는 setInterval에서 구한 메모리 최댓값 저장

시작하기 전에 현재 프로세스가 사용하는 메모리의 양을 구하고 로그를 받아오는 동안 사용한 메모리 사용량의 최댓값을 구하였습니다.
그 후에 이 둘의 차를 이용하여 로그를 받아오는 코드가 얼마나 많은 메모리를 사용하는지 유추해 볼 수 있었습니다.

256, 1690, 2342, 4014, 5155, 7288, 8392, 9070, 11581, 14153, 20761개의 로그에 대해 최대 8개까지 쓰레드를 사용해서 걸리는 시간과 소요하는 메모리 양을 구해보았습니다. (멘토님의 조언으로 최대 로그의 개수를 20000까지 제한하였습니다)
다음은 총 3번 평가하여 평균값을 낸 데이터입니다.

1. gen

https://github.com/kubernetes-client/gen
로그 수 : 256개

시간 그래프 메모리 그래프
시간 그래프 메모리 그래프

2. C-Plus-Plus

https://github.com/TheAlgorithms/C-Plus-Plus
로그 수 : 1,690개

시간 그래프 메모리 그래프
시간 그래프 메모리 그래프

3. github ranking

https://github.com/EvanLi/Github-Ranking
로그 수 : 2,342개

시간 그래프 메모리 그래프
시간 그래프 메모리 그래프

4. vitest

https://github.com/vitest-dev/vitest
로그 수 : 4,014개

시간 그래프 메모리 그래프
시간 그래프 메모리 그래프

5. SmartThingsPublic

https://github.com/SmartThingsCommunity/SmartThingsPublic
로그 수 : 5,155개

시간 그래프 메모리 그래프
시간 그래프 메모리 그래프

6. argo-cd

https://github.com/argoproj/argo-cd
로그 수 : 7,288개

시간 그래프 메모리 그래프
시간 그래프 메모리 그래프

7. jest

https://github.com/jestjs/jest
로그 수 : 8,392개

시간 그래프 메모리 그래프
시간 그래프 메모리 그래프

8. googleapis

https://github.com/googleapis/googleapis
로그 수 : 9,070개

시간 그래프 메모리 그래프
시간 그래프 메모리 그래프

9. github

https://github.com/atom/github
로그 수 : 11,581개

시간 그래프 메모리 그래프
시간 그래프 메모리 그래프

10. infer

https://github.com/facebook/infer
로그 수 : 14,153개

시간 그래프 메모리 그래프
시간 그래프 메모리 그래프

11. cypress

https://github.com/cypress-io/cypress
로그 수 : 20,761개

시간 그래프 메모리 그래프
시간 그래프 메모리 그래프

로그가 1000개 이상인 경우, 쓰레드 수가 증가함에 따라 작업 속도가 빨라지는 경향을 확인할 수 있었습니다.
그러나 과도하게 많은 쓰레드를 사용할 경우, 메모리 사용량이 크게 증가하는 반면 작업 속도 개선은 상대적으로 미미했습니다.
정확한 수치 분석은 진행되지 않았지만, CPU 코어 수의 절반 정도의 쓰레드를 사용했을 때 가장 효율적인 성능을 보인다고 생각하였습니다. (현재 저의 코어 수는 8개 입니다.)

따라서 쓰레드의 개수가 1000개 이상일 때, 코어 수의 반 개의 쓰레드를 활용하여 작업 진행하므로써 전에 코어 수 - 1개의 쓰레드를 사용했을 때보다 작업 속도를 최적화하면서도 메모리 사용량을 효과적으로 관리할 수 있게 되었습니다.

Work list

  • 쓰레드의 개수가 1000개 이상일 때, 코어 수의 반 개의 쓰레드를 활용하여 작업 진행

Discussion

코어 수의 반 개의 쓰레드를 활용하는 방식이 정확한 정답은 아닙니다. 하지만 확실히 이전 방식보다 적절한 메모리를 사용하여 작업 시간을 단축한다는 것은 맞다고 생각합니다.

Copy link
Contributor

@ytaek ytaek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

멋진 분석 리포트 입니다 👍👍👍👍👍👍👍👍👍

조금만 데이터를더 파고 들어가보자면,

  • 2000개 이후부터는 2개 정도만 해도 성능이 확 좋아지네요.
  • 코어의 반이라고 해도, 요새는 고성능, 저전력 코어가 나눠지니까 1/2로 하는 것이 답이 아닐 수도 있을 것 같아요.
    (아마도 지금 코어 개수는 늘어나는데 linear하게 안 줄어드는걸 보면 해당 이슈일지도?)
  • 심플하게 가면 그냥 코어 2~3개만 사용하게 만들어도 왠지 충분할 것 같다는 생각도 듭니다!

분석 리포트 넘 재밌게 잘 봤습니다!

@BeA-Pro
Copy link
Contributor Author

BeA-Pro commented Oct 2, 2024

저도 동의합니다, 그럼 최대 3개로 생성하는 것으로 수정하겠습니다!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants