Напишите код, чтобы загрузка процессора отображала синусоидальную волну - PullRequest
25 голосов
/ 15 февраля 2009

Напишите код на вашем любимом языке и пусть Windows Task Manager представляет синусоида в истории использования процессора.

Это технический опрос от Microsoft China. Я думаю, что это хороший вопрос. Особенно стоит знать, как кандидат понимает и находит решение.

Редактировать : Это хороший момент, если речь может идти о многоядерных процессорах.

Ответы [ 5 ]

15 голосов
/ 15 февраля 2009

Интервал времени потока в Windows составляет 40 мс, iirc, так что это может быть хорошим числом для использования в качестве отметки 100%.

unsigned const TIME_SLICE = 40;
float const PI = 3.14159265358979323846f;
while(true)
{
    for(unsigned x=0; x!=360; ++x)
    {
        float t = sin(static_cast<float>(x)/180*PI)*0.5f + 0.5f;
        DWORD busy_time = static_cast<DWORD>(t*TIME_SLICE);
        DWORD wait_start = GetTickCount();
        while(GetTickCount() - wait_start < busy_time)
        {
        }
        Sleep(TIME_SLICE - busy_time);    
    }
}

Это дало бы период около 14 секунд. Очевидно, это предполагает, что в системе нет другого значительного использования ЦП, и вы используете его только на одном процессоре. Ничто из этого на самом деле не так часто встречается в реальности.

9 голосов
/ 16 февраля 2009

Вот немного измененное решение @ flodin в Python:

#!/usr/bin/env python
import itertools, math, time, sys

time_period = float(sys.argv[1]) if len(sys.argv) > 1 else 30   # seconds
time_slice  = float(sys.argv[2]) if len(sys.argv) > 2 else 0.04 # seconds

N = int(time_period / time_slice)
for i in itertools.cycle(range(N)):
    busy_time = time_slice / 2 * (math.sin(2*math.pi*i/N) + 1)
    t = time.clock() + busy_time
    while t > time.clock():
        pass
    time.sleep(time_slice - busy_time);    

Кривая CPU может быть настроена с использованием параметров time_period и time_slice.

7 голосов
/ 15 февраля 2009

Хорошо, у меня есть другое, возможно, ЛУЧШЕЕ решение, чем мой первый ответ.

Вместо того, чтобы пытаться манипулировать ЦП, вместо этого подключиться к приложению диспетчера задач, заставить его рисовать то, что вы хотите, вместо результатов ЦП. Возьмите объект GDI, который строит график и т. Д. Вроде «Обман», но они не сказали, что вам приходилось манипулировать процессором

Или даже перехватить вызов из диспетчера задач, который получает CPU%, возвращая вместо этого синусоидальный результат.

3 голосов
/ 15 февраля 2009

С буквально сотнями (тысячами?) Потоков, которые сегодня выполняет ПК, я могу подумать, что единственный способ приблизиться к этому - опросить использование ЦП как можно быстрее, и если бы% использования был ниже, чем должно быть на кривой, чтобы запустить короткий метод, который просто сбивает цифры. Это, по крайней мере, принесет типичное низкое использование UP, когда это необходимо, но я не могу придумать хороший способ, чтобы ПОНИЗИТЬ его без какого-либо контроля над другими потоками и выполнения таких действий, как понижение их приоритета.

0 голосов
/ 15 февраля 2009

Примерно так:

while(true)
{
    for(int i=0;i<360;i++)
    {
       // some code to convert i into radians if needed
       ...
       Thread.Sleep(Math.Sin(i)*something_that_makes_it_noticeable_number_of_ms+something_that_makes_it_non_negative)
       // some work to make cpu busy, may be increased to bigger number to see the influence on the cpu.
       for(j=0;j<100;j++);
    }
}
...