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

为什么有些单线程的进程在任务管理器里实际占用双线程甚至更多线程?

  •  
  •   ruri · 2020-06-02 20:48:48 +08:00 via Android · 2337 次点击
    这是一个创建于 1610 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,为什么有些单线程的进程在任务管理器里实际占用双线程甚至更多线程? 我现在手头两台电脑,一台 r7 1700x@4ghz 全核,一台 i3 [email protected] 全核,都安装 LTSC,某个游戏在 1700x 上运行时,任务管理器可以看到只吃单线程( 8c16t ),其余线程基本 0%,个别在 5%以内。而这个游戏在 2120 上运行时,任务管理器却显示 4 线程( 2c4t )全都被吃了,而且每个逻辑线程占用率曲线图几乎一模一样,大约在 40-70%之间浮动的样子。 有大佬能讲讲这是什么原因吗?是 intel 在处理器设计上和 zen 架构不一样导致的吗?还是说仅仅只是 windows 的任务管理器显示有误?

    11 条回复    2020-06-30 04:37:43 +08:00
    xyjincan
        1
    xyjincan  
       2020-06-02 21:38:13 +08:00
    各种系统,编译器,系统,CPU 帮你优化加速了
    hcocoa
        2
    hcocoa  
       2020-06-02 23:12:52 +08:00   ❤️ 1
    程序检测到非 Intel CPU 可能会故意负优化: https://www.solidot.org/story?sid=15544
    jim9606
        3
    jim9606  
       2020-06-03 02:45:11 +08:00
    相比起之前的系统,win10 的进程调度会将单线程任务按时间片分散到多个核心中而不是锁定在一个核心上。
    至于这样有啥好处,我也不知道。
    msg7086
        4
    msg7086  
       2020-06-03 04:12:38 +08:00 via Android
    单线程占用多个 CPU 线程不是很正常的吗…
    操作系统让这个线程在多个核心里切换啊。

    比如 4 个核心线程,每个线程负责 25%的工作呗。
    分散是标准操作,可以降低单个核心的负载,凉快,不至于一小块地方特别热。
    至于 ryzen,因为有单核睿频差异,所以需要优先使用最优的核心。
    systemcall
        5
    systemcall  
       2020-06-03 09:34:56 +08:00 via Android
    架构不一样,牵扯到的东西很多
    而且游戏的话,有可能是显卡驱动的占用,显卡控制成一样的试试
    CNife
        6
    CNife  
       2020-06-03 09:48:47 +08:00
    这个问题其实挺复杂的,我提一个点,不知道大佬们有什么看法。

    首先,程序是单线程程序,但运行程序的虚拟机/运行时不一定是。有 GC 的语言,必须在用户线程外开 GC 线程,运行时就不可能是单线程。比如下面的代码

    ```Java
    public class Main {
    public static void main(String[] args) {
    Thread.getAllStackTraces()
    .keySet()
    .stream()
    .map(Thread::getName)
    .sorted()
    .forEach(System.out::println);
    }
    }
    ```

    在 Hotspot JVM 14.0.1 中运行的结果是这样的:

    Attach Listener
    Common-Cleaner
    Finalizer
    Notification Thread
    Reference Handler
    Signal Dispatcher
    main

    在 main 线程之外有多达 6 个线程,整个 JVM 当然不是单线程程序。

    不光是像 Java,Python,JavaScript 这样在虚拟机里运行的语言,像 Go 这样虽然编译成了 native binary,但仍然有 GC 和 runtime 的语言,依然会有多个 goroutine 同时运行,同样不是单线程。

    可以说,在今天,只有那些没有 GC 的语言才可以实现真正的单线程程序,多线程程序才是最常见的程序。
    BingoXuan
        7
    BingoXuan  
       2020-06-03 13:52:16 +08:00 via Android
    @CNife
    不对吧,虚拟机和程序不应该混为一起把。应该按程序可交由系统调度线程数量分才对。
    CNife
        8
    CNife  
       2020-06-03 16:35:34 +08:00
    @BingoXuan 我提这个点的意思是,虽然程序本身是单线程的,但实际上运行起来之后是多线程的,问题「单线程的进程」本身就不成立。
    ruri
        9
    ruri  
    OP
       2020-06-30 01:25:57 +08:00 via Android
    @hcocoa 原来如此……我那个游戏还真是 2010 年开测的游戏,按此推算,至少是 2 、3 年前开发,那就有很大可能是被未移除 AMD DEBUFF 的 intel 编译器编译的。
    ruri
        10
    ruri  
    OP
       2020-06-30 01:28:05 +08:00 via Android
    @jim9606 如果这样,AMD 那边应该也是和 intel 相似的 CPU 占用才对呀?但实际上 AMD 那边却持续只占用单线程,而且始终是固定的线程编号(例如始终占用 CPU 5 )。而 intel 那边不仅 4 线程均被占用,且占用率曲线几乎都可以重叠。
    jim9606
        11
    jim9606  
       2020-06-30 04:37:43 +08:00
    @ruri 我才发现你是用 1700X 跟好多年前的 2120 比。这两者的单核性能差距比较大吧,而且 2120 不支持 AVX2 。这有可能影响 OS 调度的策略。

    不清楚你的 LTSC 是哪一年的,1903 开始的调度器才能正确选择优质核心,外媒说对 Zen2 性能影响较大,不知道这个是不是适用于 Zen/Zen+。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5460 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 07:28 · PVG 15:28 · LAX 00:28 · JFK 03:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.