【问题标题】:Write code to make CPU usage display a sine wave编写代码使 CPU 使用率显示正弦波
【发布时间】:2010-10-07 18:43:47
【问题描述】:

用您喜欢的语言编写代码 并让 Windows 任务管理器代表 CPU 使用历史记录中的正弦波。

这是来自微软中国的技术面试测验。 我认为这是一个很好的问题。尤其值得了解候选人如何理解和找出解决方案。

编辑:如果可能涉及多核(cpu)的情况,这是一个好点。

【问题讨论】:

  • 你要去微软中国面试吗?
  • 不。这不是我的经验。但我现在确实在找新工作:)

标签: windows cpu-usage trigonometry


【解决方案1】:

这是一个在 Python 中稍作修改的@flodin's solution

#!/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.perf_counter() + busy_time
    while t > time.perf_counter():
        pass
    time.sleep(time_slice - busy_time);    

可以使用 time_periodtime_slice 参数微调 CPU 曲线。

【讨论】:

    【解决方案2】:

    如今,一台 PC 运行了数百(数千?)个线程,我能想到的唯一方法就是尽可能快地轮询 CPU 使用率,并且如果使用率低于应有的水平在曲线上,启动一种只会搅动数字的简短方法。这至少会在需要的地方提高典型的低使用率,但如果不以某种方式控制其他线程并执行诸如强制降低优先级之类的操作,我想不出一种降低它的好方法。

    【讨论】:

      【解决方案3】:

      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 使用率,并且您仅在单个 CPU 上运行它。这些在现实中都不是很常见。

      【讨论】:

      • 循环测试应该是GetTickCount() - wait_start
      • 如果x &gt; 180 然后t &lt; 0,DWORD 是无符号的,因此您绘制的是 abs(sin(x)),而不是 sin(x)。 stackoverflow.com/questions/551494/…
      • 修复了 sin(x) 的范围。我现在实际上已经在 Windows 上尝试过了,昨天我无法访问 Windows 机器。它可以工作...好的,但是您需要设置进程的 CPU 亲和性。精度也很差,尤其是在 CPU 使用率较低的情况下。
      【解决方案4】:

      类似这样的:

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

      【讨论】:

      • for 循环什么都不做,因此它被优化了。你留下了一个无限的while循环,它只是做一个睡眠。例如你得到的负载几乎为零。
      【解决方案5】:

      好的,我有一个不同的,可能比我的第一个答案更好的解决方案。

      与其尝试操纵 CPU,不如挂钩到任务管理器应用程序,强制它绘制您想要的内容,而不是 CPU 结果。接管绘制图形的 GDI 对象等。有点“作弊”,但他们没有说你必须操纵 CPU

      或者甚至挂钩从任务管理器获取 CPU % 的调用,改为返回正弦结果。

      【讨论】:

      • 这说明了糟糕的需求(过于笼统,无法解释)和伟大的需求(具体而具体)之间的区别。还有……在盒子里思考和在盒子外面思考的区别。
      猜你喜欢
      • 2020-02-24
      • 1970-01-01
      • 2015-12-16
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 2015-02-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多