What do the terms “CPU bound” and “I/O bound” mean?

  • CPU bound
  • I/O bound
    • disk
    • networking
    • communication

It’s pretty intuitive:

A program is CPU bound if it would go faster if the CPU were faster, i.e. it spends the majority of its time simply using the CPU (doing calculations). A program that computes new digits of π will typically be CPU-bound, it’s just crunching numbers.

A program is I/O bound if it would go faster if the I/O subsystem was faster. Which exact I/O system is meant can vary; I typically associate it with disk, but of course networking or communication in general is common too. A program that looks through a huge file for some data might become I/O bound, since the bottleneck is then the reading of the data from disk (actually, this example is perhaps kind of old-fashioned these days with hundreds of MB/s coming in from SSDs).

stackoverflow CPU Scheduling

处理器更优先于调度I/O消耗型进程?

reference 这篇文字的最后一段说处理器更倾向于优先调度I/O消耗型的进程,因为是为了程序能够及时响应用户的交互。 但是I/O消耗型的进程在等待用户的输入时,难道不是被阻塞吗? 等用户输入时才发生中断,然后被唤醒处理用户输入?

个人理解。Linux 有个CFS 完全公平调度算法,大意是说,调度两个进程时,根据进程实际已经使用的cpu 时间占总时间的比例来判断,对于io消耗型进程执行时间越长,其对应比例越高,处理器消耗型进程相对很容易抢占执行,之后执行很短时间就结束,使得处理器消耗性响应速度很快

cpu中断

linux中,cpu主要用于中断、内核和用户进程的任务处理,优先级为中断>内核>用户进程,下面先讲述三个重要的概念。

上下文切换

每个cpu(多核cpu中的每个cpu)在同一时间只能执行一个线程,linux采用的是抢占式调度。为每个线程分配一定的执行时间, 当到达执行时间、线程中有io阻塞或高优先级的线程要执行时,linux将切换执行的线程,在切换时要存储目前的线程的执行状态, 并恢复要执行的线程的状态,这个过程就是上下文切换。对于java应用而言,典型的是在进行文件io操作、网络io操作、锁等待或者线程sleep时, 当前线程会进入阻塞或休眠状态,从而触发上下文切换,上下文切换过多会造成内核占据较多的cpu使用,从而使应用响应速度变慢。

运行队列

每个cpu核都会维护一个可运行的线程队列,例如一个4核的cpu,java应用里启动了8个线程,且这8个线程都处于可运行状态, 那么在分配平均的情况下每个cpu中的运行队列就会有2个线程。通常而言,系统的load主要由cpu运行队列来决定。

系统服务(这里不局限于golang写的后台服务,也包括c++,java等后台语言)需要考虑的两个问题

  1. 系统的资源使用情况

    • (cpu利用率,内存分配情况等,runtime和syscall都提供了支持,这个是系统内部性质,往往是设计系统资源问题,需要在设计的时候慎重考虑)
  2. 系统的服务情况

    • (就是服务时延,这个是client可以直接感知的,往往是client最关注的,决定了服务的qps)

提前评估系统的资源消耗是很重要的,在公司里面,能提供选择的机器类型是很多种的。

  • 比如腾讯,往往动则上亿qq号的量,很多时候需要在内存中cache用户的实时信息,如果内存评估不对,后面如果要进行机器迁移,则比较麻烦。
  • 另外,cpu的数目太少,则并发性弱,影响服务的性能,特别是在一台机器上部署了多个服务后,抢cpu,抢内存的情况则格外严重,并且,如果把io密集程序跟cpu密集程序放到一起,io密集程序还可能会把耗内存的cpu程序给挤到swap中去导致服务出现间歇性的大量失败。