2009-02-15 3 views
25

Введите код на ваш любимый язык и позвольте диспетчеру задач Windows представлять синус-волну в истории использования CPU.Напишите код, чтобы использовать использование ЦП синусоиды

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

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

+1

Собираетесь ли вы провести интервью с Microsoft China? – Jedidja

+0

Nope.It не мой опыт. Но я действительно ищу новую работу прямо сейчас :) – chagel

ответ

15

Врезка времени потока в 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 секунд. Очевидно, это предполагает, что в системе нет другого значительного использования процессора, и что вы используете его только на одном CPU. Ни одно из них на самом деле не так распространено в реальности.

+0

Тестирование цикла должно быть GetTickCount() - wait_start peterchen

+0

Правильно, я переписал код. – flodin

+0

if'x> 180' then 't <0', DWORD - без знака, поэтому вы рисуете абс (sin (x)), а не sin (x). http://stackoverflow.com/questions/551494/write-code-to-make-cpu-usage-display-a-sine-wave/551696#551696 - – jfs

3

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

7

Хорошо, у меня есть другое, возможно, более быстрое решение, чем мой первый ответ.

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

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

+0

Думаю, это возможно, если мы позвоним монитору производительности на CPU. – chagel

+7

Это иллюстрирует разницу между плохими требованиями (слишком общее, место для интерпретации) и отличными требованиями (конкретными и конкретными). И ... разница между мышлением в коробке и из коробки. – Kit

-2

Что-то вроде этого:

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++); 
    } 
} 
+1

цикл for ничего не делает, и поэтому он оптимизируется. У вас остался бесконечный цикл, который просто сон. например вы получаете нулевую нагрузку almot. –

+0

Это был просто пример, чтобы представить «работу». –

9

Вот немного измененный @flodin's solution в 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);  

ЦП-кривая может быть доработаны с помощью time_period и time_slice параметров.

Смежные вопросы