[Beauty of Programming 1] Drawing Curves with CPU Usage

Getting the CPU to run at full load is actually quite simple – just write an infinite loop and the OS will allocate more and more time slices to it. However, modern processors are multi-core. For example, my computer has 4 cores, so you’ll find the CPU stays around 25-27% and never reaches 100%.

To reach 100%, you just need to use multithreading.

The most provocative statement I saw today was:

“I dare you to make the CPU draw a circle.” I was completely stunned at that moment…

Now let’s look at the 50% case. The book “Beauty of Programming” says that alternating between “sleep for one time slice, work for one time slice” should achieve 50%. But I found the results were not great. Even using GetTickCount, the effect was poor because the computer has other programs running as well.

 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
void Work(DWORD time)
{
    DWORD now = GetTickCount();
    for(;GetTickCount() <<- endstream>> now + time;)
    {
    }
}
DWORD WINAPI DrawThread(LPVOID lParam)
{
    double deta = 0.1f;
    while (true)
    {
        double time = 500 + 500 * sin(deta);
        Work(time);
        Sleep(1000-time);
        deta += 0.1f;
    }
    return 0;
}
int main()
{
    HANDLE hThread[4];
    DWORD idThread[4];
    hThread[0] = CreateThread(0,0,DrawThread,NULL,0,& idThread[0]);
    hThread[1] = CreateThread(0,0,DrawThread,NULL,0,& idThread[1]);
    hThread[2] = CreateThread(0,0,DrawThread,NULL,0,& idThread[2]);
    hThread[3] = CreateThread(0,0,DrawThread,NULL,0,& idThread[3]);
    SetThreadAffinityMask(hThread[0], 0x00000001);
    SetThreadAffinityMask(hThread[1], 0x00000010);
    SetThreadAffinityMask(hThread[2], 0x00000100);
    SetThreadAffinityMask(hThread[3], 0x00001000);

    WaitForSingleObject(hThread[0], INFINITE);
    WaitForSingleObject(hThread[1], INFINITE);
    WaitForSingleObject(hThread[2], INFINITE);
    WaitForSingleObject(hThread[3], INFINITE);

    return 0;
}