Escribir código para hacer que el uso de la CPU muestre una onda sinusoidal


Escribe código en tu idioma favorito y deje que el Administrador de Tareas de Windows represente una onda sinusoidal en el Historial de Uso de la CPU.

Este es un cuestionario de entrevista técnica de Microsoft China. Creo que es una buena pregunta. Especialmente vale la pena saber cómo el candidato entender y averiguar la solución.

Editar : Es un buen punto si puede involucrar casos de varios núcleos(cpu).

Author: Viktor Dahl, 2009-02-15

5 answers

Un corte de tiempo de hilo en Windows es 40ms, iirc, por lo que podría ser un buen número para usar como la marca del 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);    
    }
}

Esto daría un período de aproximadamente 14 segundos. Obviamente, esto asume que no hay otro uso significativo de cpu en el sistema, y que solo lo está ejecutando en una sola CPU. Ninguno de estos es realmente tan común en la realidad.

 15
Author: flodin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-16 07:25:52

Aquí hay una solución ligeramente modificada @flodin en 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);    

Una curva de CPU se puede ajustar usando los parámetros time_period y time_slice.

 9
Author: jfs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:01:17

Ok Tengo una solución diferente, probablemente MEJOR que mi primera respuesta.

En lugar de tratar de manipular la CPU, en lugar de enganchar en la aplicación administrador de tareas, obligarlo a dibujar lo que desea que en lugar de resultados de la CPU. Toma el control del objeto GDI que traza el gráfico, etc. Una especie de" Trampa", pero no dijeron que tenía que manipular la CPU

O incluso enganchar la llamada del administrador de tareas que obtiene el % de CPU, devolviendo un resultado sinusoidal en su lugar.

 7
Author: Neil N,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-15 20:13:02

Con los literalmente cientos (miles?) de hilos de un PC se ejecuta hoy en día, la única manera que puedo pensar incluso acercarse sería sondear el uso de la CPU lo más rápido posible, y si el% de uso estaba por debajo de donde debería estar en la curva, para disparar un método corto que solo produce números. Eso al menos traerá el típico bajo uso donde sea necesario, pero no puedo pensar en una buena manera de BAJARLO sin tomar de alguna manera el control de otros hilos, y hacer algo como forzar su prioridad inferior.

 3
Author: Neil N,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-12 01:56:14

Algo como esto:

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++);
    }
}
 -2
Author: Alex Reitbort,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-15 20:17:43