While문이라 For문에서 무한루프를 돌리거나 오래도록 반복해서 작업을 해야되는 경우가 있습니다. 이때 CPU부하가 올라가는데 Sleep을 적절이 이용해서 CPU부하를 줄일 수 있습니다. Sleep을 하게되면 다른 스레드로 컨텍스트 스위칭을 하여 다른 스레드가 작업을 하게 합니다. 이렇게 해서 CPU부하도 줄이고 다른 스레드에서 작업을 할 수 있게 합니다. Sleep(0)과 0보다 큰 경우는 약간 다르게 동작하는데 관련 부분에 대해 알려드리겠습니다.
1. Sleep(0)
MSDN자료를 확인해보면 인수값이 0인 경우 우선순위가 동일한 스레드에서 컨텍스트 스위칭하는 부분을 알 수 있습니다.
2. Sleep(0보다큰 경우)
대부분 Sleep을 쓸 경우 해당시간만큰 대기를 하고 싶을 경우에 사용하는 경우가 많습니다. 이때는 우선순위에 상관없이 다른 스레드에 실행정보를 넘겨주게 됩니다. 딜레이 시간을 두어 CPU부하를 줄일 수 있습니다.
3. Sleep값에따른 CPU점유률 비교
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;
namespace SleepTester
{
class Program
{
static void Main()
{
// 프로세서 개수 가져오기
int processorCount = Environment.ProcessorCount;
// PerformanceCounter 객체 생성
PerformanceCounter[] cpuCounters = new PerformanceCounter[processorCount];
for (int i = 0; i < processorCount; i++)
{
cpuCounters[i] = new PerformanceCounter("Processor", "% Processor Time", i.ToString());
}
int loopCnt = 1000;
float totAverage = 0.0f;
Console.WriteLine($"======================================================================================");
Console.WriteLine($"Start Sleep(X)");
for (int i = 0; i < loopCnt; i++)
{
if (i % 100 == 0)
{
float averageCpuUsage = GetCpuUseage(processorCount, cpuCounters);
Console.WriteLine("Average CPU Usage: {0}%", averageCpuUsage);
totAverage += averageCpuUsage;
}
}
Console.WriteLine($"totAverage:{totAverage / 10}");
Console.WriteLine($"======================================================================================");
Console.WriteLine();
totAverage = 0.0f;
Console.WriteLine($"Start Sleep(0)");
for (int i = 0; i < loopCnt; i++)
{
System.Threading.Thread.Sleep(0);
if (i % 100 == 0)
{
float averageCpuUsage = GetCpuUseage(processorCount, cpuCounters);
Console.WriteLine("Average CPU Usage: {0}%", averageCpuUsage);
totAverage += averageCpuUsage;
}
}
Console.WriteLine($"totAverage:{totAverage / 10}");
Console.WriteLine($"======================================================================================");
Console.WriteLine();
totAverage = 0.0f;
Console.WriteLine($"Start Sleep(1)");
for (int i = 0; i < loopCnt; i++)
{
System.Threading.Thread.Sleep(1);
if (i % 100 == 0)
{
float averageCpuUsage = GetCpuUseage(processorCount, cpuCounters);
Console.WriteLine("Average CPU Usage: {0}%", averageCpuUsage);
totAverage += averageCpuUsage;
}
}
Console.WriteLine($"totAverage:{totAverage / 10}");
Console.WriteLine($"======================================================================================");
Console.ReadLine();
}
private static float GetCpuUseage(int processorCount, PerformanceCounter[] cpuCounters)
{
// 각 프로세서의 CPU 사용량 측정
float[] cpuUsages = new float[processorCount];
for (int j = 0; j < processorCount; j++)
{
cpuUsages[j] = cpuCounters[j].NextValue();
}
// CPU 평균 사용량 계산
float averageCpuUsage = 0;
float sum = 0;
foreach (float value in cpuUsages)
{
sum += value;
}
averageCpuUsage = sum / cpuUsages.Length;
return averageCpuUsage;
}
}
}
|
cs |
실행결과
Sleep을 하지 않았을 경우와 Sleep(0) Sleep(1)을 비교해봤습니다. Sleep하지 않았을 경우와 Sleep(0)은 프로세스가 많고 하다보니 큰차이가 없어 보이고, Sleep(0)인 경우 컨텍스트 스위칭이 이루어져 실제로는 별 차이가 없어 보이지만 다른 스레드가 처리 할 수 있도록 해주기 때문에 다른 동작을 수행 할 수 있게 합니다. Sleep(1)의경우는 해당시간 만큼 대기를 하기때문에 현저히 Cpu부하가 감소되는 부분을 확인 할 수 있습니다.
참고
https://learn.microsoft.com/ko-kr/dotnet/api/system.threading.thread.sleep?view=net-7.0
'프로그래밍 > C#' 카테고리의 다른 글
[C#] 성능개선 팁 List<T>의 Capacity값을 수동조정 (1) | 2024.11.13 |
---|---|
[C#] 폼사이즈 수정안될때 (0) | 2024.01.06 |
[c#] postgresql 연동 (0) | 2023.06.10 |
[C#] 네이버센스 SMS문자보내기 (0) | 2023.02.14 |
[C#] 설치파일 만들기 (0) | 2023.01.16 |