V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
GLee9507
V2EX  ›  Android

Android 面试奇怪问题

  •  
  •   GLee9507 · 2018-05-21 16:06:24 +08:00 · 8408 次点击
    这是一个创建于 2138 天前的主题,其中的信息可能已经有所发展或是发生改变。
    今天面试一家做车载的公司,被问到一个奇怪的问题。---如何优化、降低 CPU 使用率?
    唉,没回答上来,我觉得 CPU 使用率是无法人为干预的,大家怎么看?
    第 1 条附言  ·  2018-05-21 17:09:14 +08:00
    问题描述有误,正确描述:
    如何优化、降低 CPU 占用率?(不是使用率)
    第 2 条附言  ·  2018-05-22 14:08:02 +08:00
    感谢大家的回复,这次面试没有白去。
    58 条回复    2018-05-23 21:37:06 +08:00
    jerry12547
        1
    jerry12547  
       2018-05-21 16:17:16 +08:00
    。。说个抖机灵的方法。。选个 intel X? 18 个框框 使用率肯定降低了(斜眼)
    sanjusss
        2
    sanjusss  
       2018-05-21 16:21:53 +08:00
    可能指的是程序的 CPU 占用率吧。
    dychenyi
        3
    dychenyi  
       2018-05-21 16:25:46 +08:00
    运用 GPU 运算? 车载没那么高级吧。

    又或者说他就希望你说出使用针对优化的库而已?针对硬件编译优化驱动,上层应用?
    又或者是用空间换时间?
    Humorce
        4
    Humorce  
       2018-05-21 16:26:22 +08:00 via iPhone
    控制 socket 线程、媒体资源文件的处理等等 不都是可以通过人为优化实现吗?
    deadEgg
        5
    deadEgg  
       2018-05-21 16:31:24 +08:00
    面试官说的也太空了
    gystry
        6
    gystry  
       2018-05-21 16:36:51 +08:00 via Android
    面试官炫技
    enenaaa
        7
    enenaaa  
       2018-05-21 16:37:36 +08:00
    意思就是优化执行效率, 减少 cpu 占用吧。
    比如游戏,经常因为高 cpu/gpu 占用导致手机过热,掉电过快问题。
    lincanbin
        8
    lincanbin  
       2018-05-21 16:43:39 +08:00 via Android
    提升程序性能
    CrisTao
        9
    CrisTao  
       2018-05-21 16:46:25 +08:00
    cpu 的话不就是做性能优化么,多线程、io、ui (虽然说车载没啥 ui 的)太多可以处理的
    nullcc
        10
    nullcc  
       2018-05-21 16:47:30 +08:00
    这个题目问得比较宽泛,答全了比较难,我个人认为有一些点可以考虑:

    1. 写无限循环的时候要注意检查跳出条件
    2. 计算密集型工作,看看是否能拆分计算过程,将计算分摊到多个 CPU (或者多台计算机)上进行
    3. 如果不需要在线的实时计算,可以实现成定时任务离线计算,最后再汇总结果
    4. 某些计算可以尝试利用 GPU
    5. 一些代价高的计算,如果可以忍受一定的非实时性,可以缓存结果
    atfeel
        11
    atfeel  
       2018-05-21 16:49:32 +08:00
    降低程序刷新率,CPU 就降下来了
    GLee9507
        12
    GLee9507  
    OP
       2018-05-21 16:58:49 +08:00
    @Humorce 控制线程、媒体资源文件,请问如何优化
    Arsenal16
        13
    Arsenal16  
       2018-05-21 17:04:12 +08:00
    CPU 的占用率应该可以人为控制, 搜一下微软面试题有讲这个的.
    GLee9507
        14
    GLee9507  
    OP
       2018-05-21 17:05:45 +08:00
    @Arsenal16 难道是 sleep 一下?
    GLee9507
        15
    GLee9507  
    OP
       2018-05-21 17:06:38 +08:00
    @nullcc 当时我想应用层开发也不需要什么密集型计算,就算有密集型计算多说开几个线程,充分利用多核心而已,也谈不上什么优化
    jinhan13789991
        16
    jinhan13789991  
       2018-05-21 17:08:58 +08:00
    关机啊~
    Humorce
        17
    Humorce  
       2018-05-21 17:13:06 +08:00 via iPhone
    @GLee9507
    这个是根据产品实际运用场景去决定如何优化的,
    进行搜索都能找到一些优化方式了。
    #9 #10 的两位也提供了更多的优化方向。
    nullcc
        18
    nullcc  
       2018-05-21 17:38:24 +08:00
    @Arsenal16 我记得《编程之美》有一题让 CPU 占用率曲线呈正弦图形的
    wizardoz
        19
    wizardoz  
       2018-05-21 17:43:49 +08:00
    我知道提高 CPU 占用率的方法,坐等降低的方法
    ssynhtn
        20
    ssynhtn  
       2018-05-21 17:44:57 +08:00
    面试是双向的, 问题提的不好也说明对方技术实力不行
    zynlp
        21
    zynlp  
       2018-05-21 18:14:55 +08:00 via iPhone
    尽量用 gpu 算不就降低 cpu 利用率了吗?
    holmesabc
        22
    holmesabc  
       2018-05-21 18:38:02 +08:00
    这玩意肯定是双方相互理解上去了问题。
    对方肯定是想问怎么优化性能之类的。


    这个肯定要先知道那里有问题,再针对问题对解喽。

    所以说看 profile,找问题题。再列举一些可能的性况,如何解就好了。
    zhoucan007
        23
    zhoucan007  
       2018-05-21 18:55:49 +08:00 via Android
    android 本质上运行的还是个虚拟机,如果是我的话,会从 Java 代码优化层面去说吧
    arthasgxy
        24
    arthasgxy  
       2018-05-21 19:42:40 +08:00
    我个人感觉,,如果面试官不是大牛的话。。他其实就是想考验一下你有没有想法。。
    简单来讲,做功能,大家都会做,损一点的说法甚至可以把码农说成搬运工。

    而如果你只会写功能,不会优化,对方就会觉得你是搬运工了。。。

    当然,我感觉对方表述也有问题。。感觉像是两重意思都说得通:
    1、如何提高代码性能?
    2、如何在原有代码性能没有提高的情况下,通过某种“作弊”的手段降低 cpu 使用率,以让用户感觉到你的程序比别人的牛
    masterAtyan
        25
    masterAtyan  
       2018-05-21 19:43:12 +08:00
    @zhoucan007 android 的虚拟机是不能调优的。 @nullcc 已经说了,CPU 占用率高,本质上还是密集的逻辑运算多。像是驱动之类的,涉及 IO 的操作,跟 CPU 占用率关系不大。主要的思路还是优化算法方面,android 的话还有绘制方面可以讲,至于利用 GPU 也是高大上的事情,可以不了解
    fancyhan
        26
    fancyhan  
       2018-05-21 19:58:07 +08:00
    开放问题啊,随便说说就好,你这样是自己水平不行
    GLee9507
        27
    GLee9507  
    OP
       2018-05-22 08:17:00 +08:00
    @fancyhan
    @masterAtyan
    确实,我只说出了内存优化,布局优化,绘制优化,面试官感觉不太满意。Android 中 CPU 优化我确实不知道怎么答。。
    GLee9507
        28
    GLee9507  
    OP
       2018-05-22 08:19:51 +08:00
    @holmesabc 嗯是,我比较迟钝,可能没有 GET 到面试官提问的点,当时应该让他列举一些场景。
    GLee9507
        29
    GLee9507  
    OP
       2018-05-22 08:28:14 +08:00
    @arthasgxy 嗯,你说的对。我只说出了内存优化,布局优化,绘制优化,面试官感觉不太满意。Android 中 CPU 优化我确实不知道怎么答。
    GLee9507
        30
    GLee9507  
    OP
       2018-05-22 08:30:10 +08:00
    @nullcc Android 总不能 Thread.sleep 吧,况且我认为线程睡眠是有一定开销的
    zhuangBwang
        31
    zhuangBwang  
       2018-05-22 08:46:34 +08:00 via Android
    本质上还是想程序问对电池的优化吧
    GLee9507
        32
    GLee9507  
    OP
       2018-05-22 08:51:51 +08:00
    @zhuangBwang 不是呀,是车载终端
    zhuangBwang
        33
    zhuangBwang  
       2018-05-22 08:59:04 +08:00 via Android
    @GLee9507 我的意思是电池优化的措施一般就是降低 CPU 的占用率,所以电池怎么优化,不外乎减少过度绘制,避免密集型运算,使用 Job Schedule 等等
    GLee9507
        34
    GLee9507  
    OP
       2018-05-22 10:28:42 +08:00
    @zhuangBwang 说得对,有道理
    preach
        35
    preach  
       2018-05-22 10:42:14 +08:00
    炫技而已 这种直接不去
    iwtbauh
        36
    iwtbauh  
       2018-05-22 11:31:49 +08:00 via Android
    “ CPU 使用率是无法人为干预的”
    从某种意义上就是正确的

    CPU 通电以后,就一直是 100%占用状态。

    windows 用户打开任务管理器,看看所有进程,即使其他进程一共占用了 1%的 CPU,是不是还有一个包含“ Idle ”字样的进程占用了剩余 99%的 CPU。

    这个进程 Linux 也有,叫 swapper,但是不会显示给用户。(但其实是有的,不信去看内核源码)

    从计算机科学上讲,CPU 使用率的却无法人为干预,因为 CPU 一直都是 100%在使用。

    原因在于,操作系统实质上是一个死循环
    while (1)
    {

    }

    内核会在中断时执行其他代码,最终达到一个“安全的任务调度点”时调度执行其他任务。
    enenaaa
        37
    enenaaa  
       2018-05-22 13:19:18 +08:00
    @iwtbauh 现在的 cpu 早就可以根据负载情况来动态调整功率了。 你没发现玩大型游戏时风扇转得特别狠吗。
    操作系统是通过软硬件中断来调度的, 可不会搞死循环这套。
    599316527
        38
    599316527  
       2018-05-22 13:33:36 +08:00
    大体上讲两个方向吧,一个通过优化算法尽可能减少计算量;另一个空间换时间,缓存结果,尽量少算
    iwtbauh
        39
    iwtbauh  
       2018-05-22 13:38:57 +08:00 via Android
    @enenaaa 调整的是频率,而不是占用率,占用率是没法调整的,CPU 通电以后就会一直转,频率是可以由 CPU 驱动程序管理。但是占用率你没有办法调整,不管频率调整得再低,CPU 该转还是转,还是 100%


    这个调度和死循环并不冲突啊,,按你这么说没有中断的时候你让操作系统干什么呢,这个时候是操作系统以 idle “进程”的身份在执行这个死循环,因为 CPU 需要一直运行。
    enenaaa
        40
    enenaaa  
       2018-05-22 14:34:01 +08:00
    @iwtbauh #39
    你貌似对占用率有误解? 一个进程占用当前 cpu 的时间比例是占用率,这当然根据该进程的运行情况来确定。进程没计算需求时挂起,自然减少占用率。
    至于 cpu 总的使用率, 进入 idle 后是等待中断, 不是正常运行状态。
    iwtbauh
        41
    iwtbauh  
       2018-05-22 14:50:54 +08:00 via Android
    @enenaaa “进入 idle 后是等待中断, 不是正常运行状态。” 惊了,CPU 使用状态还有正常不正常的区别。同样是代码,你凭什么说 idle 里的代码就不是正常使用 CPU,非 idle 里的代码就是正常使用?莫非你以为编译后的内核中 idle 里的汇编机器指令和其他地方的汇编机器指令有区别?还是 CPU 能自己分辨出来代码是 idle ?等待中断不假,其实是内核用一个死循环等待中断的啊,和其他死循环编译出来的机器指令一样,对于 CPU 而言,它就是当“普通代码”一样执行 idle 里的代码而已。都是对 CPU 的“正常使用”

    另外上文的却有容易混淆的地方,占用率指的是总占用率,我表达的意思是 CPU 在指定频率下(不管多低)都是 100%使用的。
    enenaaa
        42
    enenaaa  
       2018-05-22 15:22:31 +08:00
    @iwtbauh #41
    idle 函数内执行 hlt 指令,cpu 进入暂停状态,等待下一次硬件中断。 这有啥奇怪的。难道你以为 cpu 会一直满负荷运转,主动检查各种中断嘛。
    iwtbauh
        43
    iwtbauh  
       2018-05-22 16:42:40 +08:00
    @enenaaa 拜托,hlt 是 x86 汇编指令。对于 ARM 而言,据我所知并没有等价指令存在。(其实是否在 x86 上使用我感觉也是存疑的,毕竟这个指令很早就有了,wikipedia 上说 8086 就有了,如果确实可行没道理早期时代的 Linux 内核不用它用死循环,现在不清楚),Android 设备几乎没有用 x86 CPU 的吧

    操作系统确实会去执行死循环,Linux 4.6 版本(现在 Android 似乎还在大批使用 3.x 内核?懒得找旧内核源码了),https://github.com/torvalds/linux/blob/v4.6/kernel/sched/idle.c,在 202 行执行 cpu_idle_loop 函数,这个函数就是一个死循环。

    另外我什么时候说过“主动检查各种中断”了,,中断要是主动去检测还是中断么,当然是中断产生时 cpu_idle_loop 被打断,CPU 去执行中断处理函数了,如果需要调度自然会调度。

    另外也不是满负荷运转,原因就是上面说的,基本上绝大部分设备上 CPU 频率可以调整。只是在当前频率下 CPU 并没有停止,还是一直在执行一个又一个指令。
    tempdban
        44
    tempdban  
       2018-05-22 18:19:32 +08:00 via Android
    楼上不要吵,主动检查中断,可对可不对。
    enenaaa
        45
    enenaaa  
       2018-05-22 18:22:56 +08:00
    @iwtbauh arm 有 wfi, wfe 指令。
    WFI suspends execution until one of the following events occurs:

    an exception

    an interrupt becomes pending, which would preempt if PRIMASK was clear

    a Debug Entry request, regardless of whether debug is enabled.
    iyaozhen
        46
    iyaozhen  
       2018-05-22 18:36:08 +08:00 via Android
    😂 难道楼主之前都不关心 CPU 使用率吗?我们都有 CPU、内存、电量、流量各种测试
    tianzx
        47
    tianzx  
       2018-05-22 18:56:46 +08:00 via Android
    mark
    saberpowermo
        48
    saberpowermo  
       2018-05-22 19:00:12 +08:00
    面 android 问这种问题, 居然在 v2 都不算奇怪问题了
    mark 下 向楼上的大佬们学习了。
    mashiro233
        49
    mashiro233  
       2018-05-22 19:45:35 +08:00   ❤️ 1
    @iwtbauh
    @enenaaa

    首先 x86 我不熟,如果 HLT 的作用是将 cpu 进入低功耗模式等待中断将其恢复到正常模式的话。那么 ARM 对应的有 WFI(Wait For Interrupt)指令将 cpu 进入一个低功耗模式,直到一个中断发生。在多核的情况下还有个 WFE。

    既然都贴出内核代码了,那我们不妨分析一下。首先看死循环,死循环再往下看(227 行)是不是有个 local_irq_disable()关闭中断,再之后,检查是进入 poll 轮寻(这里会重新开启中断)还是真正的 idle 模式,这里会调用
    cpuidle_idle_call(),在这里(128 行),会检查是否需要让出 idle,如果需要则让出,不需则检查当前 cpu 是否支持 idle,如果支持则调用 default_idle_call(),这里就是会调用 arch_cpu_idle(),也就是 x86 的 HLT 指令,ARM 的 WFI 指令的地方。所以很显然,内核使用了大循环没有错,但是大循环绝对不是 iwtbauh 想象的那样工作,简单点就是。

    ```
    while(1){

    }

    ```
    sampeng
        50
    sampeng  
       2018-05-22 19:47:18 +08:00
    很空泛的问题,随便答答,只要答到面试官 G 点就行了。。
    mashiro233
        51
    mashiro233  
       2018-05-22 19:47:35 +08:00
    手抖按到快捷键了发出来了…………
    ```
    while(1){
    是否需要调度?需要,让出: 不需要,idle 或者 poll。
    }

    ```
    mashiro233
        52
    mashiro233  
       2018-05-22 20:22:18 +08:00
    @iwtbauh

    针对你 39 楼的回复 `CPU 通电以后就会一直转` 这个也观点我认为也是错误的。

    我们来看 Cortex-A72 的手册 2.4.1 Dynamic power management。
    http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0488f/Chunk1121736769.html

    这里谈到了 WFI 和 WFE 的实现,其中都提到了。
    ARMv8-A architecture that puts the core in a low-power state by disabling the clocks in the core while keeping the core powered up. This reduces the power drawn to the static leakage when the core is in WFI low-power state.

    注意这个 disabling the clocks,进入 idle 之后时钟是被关闭的 cpu 本身不执行指令,但是能够被外部中断或者其他什么方式唤醒(比如 WFE 可以被其他核的 SEV 指令唤醒)。
    mashiro233
        53
    mashiro233  
       2018-05-22 20:28:12 +08:00
    说错了,是 Cortex-A57 ……
    iwtbauh
        54
    iwtbauh  
       2018-05-22 21:39:32 +08:00 via Android
    @enenaaa
    @mashiro233

    的却是我的错,抱歉了。

    另外,WFI 与 HLT 相近但并不完全一样。

    顾名思义
    HLT ( halt )是“保证” CPU 进入休眠模式
    WFI ( wait for int )是等待中断,让 CPU 进入睡眠模式是平台的“实现细节”,而不是标准和保证,对于有的 arm 平台,这个指令相当于一直执行 NOP
    mashiro233
        55
    mashiro233  
       2018-05-22 22:04:19 +08:00
    @iwtbauh
    感谢,学习了,x86 那块没确实没怎么系统研究过。😂
    wizardforcel
        56
    wizardforcel  
       2018-05-23 01:15:21 +08:00 via Android
    降低某个程序的占用率还是能做到的,sleep 了解一下。
    GLee9507
        57
    GLee9507  
    OP
       2018-05-23 08:28:14 +08:00
    @wizardforcel Android 应用 sleep 的意义何在 -。-
    fancyhan
        58
    fancyhan  
       2018-05-23 21:37:06 +08:00
    这种开放问题,往往低水平的面试官只认同他自己知道的那些方面。我想未必是你的问题
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1735 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 16:38 · PVG 00:38 · LAX 09:38 · JFK 12:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.