当前位置: 首页 > news >正文

并发任务的进化之旅

An evolutionary journey of multitasking

多重任务的进化之旅

In the beginning, computers had one CPU that executed a set of instructions written by a programmer one by one. No operating system (OS), no scheduling, no threads, no multitasking. This was how computers worked for a long time. We’re talking back when a program was assembled in a deck of punched cards, and you got in big trouble if you were so unfortunate that you dropped the deck onto the floor.

一开始,计算机只有一个CPU,一个接一个地执行程序员编写的一组指令。没有操作系统(OS),没有调度,没有线程,没有多任务。在很长一段时间里,计算机就是这样工作的。我们说的是当一个程序被组装在一副打孔卡片上时,如果你不幸把卡片掉到地板上,你就有大麻烦了。

There were operating systems being researched very early and when personal computing started to grow in the 80s, operating systems such as DOS were the standard on most consumer PCs.

人们很早就开始研究操作系统,当个人电脑在80年代开始发展时,DOS等操作系统是大多数个人电脑的标准配置。

These operating systems usually yielded control of the entire CPU to the program currently executing, and it was up to the programmer to make things work and implement any kind of multitasking for their program. This worked fine, but as interactive UIs using a mouse and windowed operating systems became the norm, this model simply couldn’t work anymore.

这些操作系统通常将整个CPU的控制权交给当前正在执行的程序,由程序员来完成工作并为程序实现任何类型的多任务处理。这种模式运行良好,但随着使用鼠标和窗口操作系统的交互式ui成为常态,这种模式就不再适用了。

Non-preemptive multitasking

非抢占式多任务

Non-preemptive multitasking was the first method used to be able to keep a UI interactive (and running background processes).

非抢占式多任务是第一种能够保持UI交互(并运行后台进程)的方法。

This kind of multitasking put the responsibility of letting the OS run other tasks, such as responding to input from the mouse or running a background task, in the hands of the programmer.

这种多任务处理将让操作系统运行其他任务的责任,例如响应来自鼠标的输入或运行后台任务,交给了程序员。

Typically, the programmer yielded control to the OS.

通常,程序员将控制权交给操作系统。

Besides offloading a huge responsibility to every programmer writing a program for your platform, this method was naturally error-prone. A small mistake in a program’s code could halt or crash the entire system.

除了将巨大的责任推卸给为您的平台编写程序的每个程序员之外,这种方法自然容易出错。程序代码中的一个小错误可能会使整个系统停止或崩溃。

Another popular term for what we call non-preemptive multitasking is cooperative multitasking. Windows 3.1 used cooperative multitasking and required programmers to yield control to the OS by using specific system calls. One badly-behaving application could thereby halt the entire system.

我们称之为非抢占式多任务的另一个流行术语是合作多任务。Windows 3.1使用协同多任务,并要求程序员通过使用特定的系统调用将控制权交给操作系统。一个行为不佳的应用程序就可能使整个系统瘫痪。

Preemptive multitasking

抢占式多任务

While non-preemptive multitasking sounded like a good idea, it turned out to create serious problems as well. Letting every program and programmer out there be responsible for having a responsive UI in an operating system can ultimately lead to a bad user experience, since every bug out there could halt the entire system.

虽然非抢占式多任务处理听起来是个好主意,但事实证明它也会产生严重的问题。让每个程序和程序员都负责操作系统中的响应性UI,最终会导致糟糕的用户体验,因为每个漏洞都可能导致整个系统瘫痪。

The solution was to place the responsibility of scheduling the CPU resources between the programs that requested it (including the OS itself) in the hands of the OS. The OS can stop the execution of a process, do something else, and switch back.

解决方案是将在请求它的程序(包括操作系统本身)之间调度CPU资源的责任置于操作系统的手中。操作系统可以停止一个进程的执行,做其他事情,然后切换回来。

On such a system, if you write and run a program with a graphical user interface on a single-core machine, the OS will stop your program to update the mouse position before it switches back to your program to continue. This happens so frequently that we don’t usually observe any difference whether the CPU has a lot of work or is idle.

在这样的系统上,如果您在单核机器上编写并运行带有图形用户界面的程序,操作系统将停止您的程序以更新鼠标位置,然后再切换回您的程序继续。这种情况发生得如此频繁,以至于我们通常不会观察到CPU是否有大量工作或空闲有任何区别。

The OS is responsible for scheduling tasks and does this by switching contexts on the CPU. This process can happen many times each second, not only to keep the UI responsive but also to give some time to other background tasks and IO events.

操作系统负责调度任务,并通过在CPU上切换上下文来完成。这个过程每秒可以发生很多次,不仅是为了保持UI响应,也是为了给其他后台任务和IO事件一些时间。

This is now the prevailing way to design an operating system.

这是现在设计操作系统的主流方式。

Later in this book, we’ll write our own green threads and cover a lot of basic knowledge about context switching, threads, stacks, and scheduling that will give you more insight into this topic, so stay tuned.

在本书的后面,我们将编写自己的绿色线程,并介绍有关上下文切换、线程、堆栈和调度的许多基本知识,这些知识将使您对这个主题有更深入的了解,请继续关注。

Hyper-threading

超线程

As CPUs evolved and added more functionality such as several arithmetic logic units (ALUs) and additional logic units, the CPU manufacturers realized that the entire CPU wasn’t fully utilized. For example, when an operation only required some parts of the CPU, an instruction could be run on the ALU simultaneously. This became the start of hyper-threading.

随着CPU的发展和增加更多的功能,如几个算术逻辑单元(alu)和额外的逻辑单元,CPU制造商意识到整个CPU没有得到充分利用。例如,当一个操作只需要CPU的某些部分时,一条指令可以同时在ALU上运行。这就是超线程的开始。

Your computer today, for example, may have 6 cores and 12 logical cores… This is exactly where hyperthreading comes in. It “simulates” two cores on the same core by using unused parts of the CPU to drive progress on thread 2 and simultaneously running the code on thread 1. It does this by using a number of smart tricks (such as the one with the ALU).

例如,你今天的电脑可能有6个核心和12个逻辑核心。这正是超线程的用武之地。它通过使用CPU的未使用部分来驱动线程2上的进程并同时在线程1上运行代码,从而在同一个内核上“模拟”两个内核。它通过使用许多聪明的技巧(比如使用ALU的技巧)来实现这一点。

Now, using hyper-threading, we could actually offload some work on one thread while keeping the UI interactive by responding to events in the second thread even though we only had one CPU core, thereby utilizing our hardware better.

现在,使用超线程,我们实际上可以在一个线程上卸载一些工作,同时通过响应第二个线程中的事件保持UI交互,即使我们只有一个CPU核心,从而更好地利用我们的硬件。

It turns out that hyper-threading has been continuously improved since the 90s. Since you’re not actually running two CPUs, there will be some operations that need to wait for each other to finish. The performance gain of hyper-threading compared to multitasking in a single core seems to be somewhere close to 30% but it largely depends on the workload.

事实证明,自上世纪90年代以来,超线程一直在不断改进。由于实际上并没有运行两个cpu,因此会有一些操作需要等待对方完成。与单核的多任务处理相比,超线程的性能增益似乎接近30%,但这主要取决于工作负载。

Multicore processors

多核处理器

As most know, the clock frequency of processors has been flat for a long time. Processors get faster by improving caches, branch prediction, and speculative execution, and by working on the processing pipelines of the processors, but the gains seem to be diminishing.

众所周知,处理器的时钟频率在很长一段时间内一直是平坦的。处理器通过改进缓存、分支预测和推测执行,以及处理处理器的处理管道来提高速度,但收益似乎正在减少。

On the other hand, new processors are so small that they allow us to have many on the same chip. Now, most CPUs have many cores and most often, each core will also have the ability to perform hyper-threading.

另一方面,新的处理器是如此之小,以至于我们可以在同一个芯片上安装许多处理器。现在,大多数cpu都有许多核心,而且大多数情况下,每个核心都有执行超线程的能力。

Do you really write synchronous code?

你真的在写同步代码吗?

Like many things, this depends on your perspective. From the perspective of your process and the code you write, everything will normally happen in the order you write it.

像许多事情一样,这取决于你的观点。从您的流程和您编写的代码的角度来看,一切通常都将按照您编写的顺序发生。

From the operating system’s perspective, it might or might not interrupt your code, pause it, and run some other code in the meantime before resuming your process.

从操作系统的角度来看,它可能会也可能不会中断您的代码,暂停它,并在恢复您的进程之前同时运行一些其他代码。

From the perspective of the CPU, it will mostly execute instructions one at a time.* It doesn’t care who wrote the code, though, so when a hardware interrupt happens, it will immediately stop and give control to an interrupt handler. This is how the CPU handles concurrency.

从CPU的角度来看,它主要是一次执行一条指令。*它不关心谁写的代码,虽然,所以当硬件中断发生时,它会立即停止并把控制权交给中断处理程序。这就是CPU处理并发的方式。

However, modern CPUs can also do a lot of things in parallel. Most CPUs are pipelined, meaning that the next instruction is loaded while the current one is executing. It might have a branch predictor that tries to figure out what instructions to load next.

然而,现代cpu也可以并行处理很多事情。大多数cpu都是流水线的,这意味着当当前指令执行时,下一条指令会被加载。它可能有一个分支预测器,试图找出下一步加载什么指令。

The processor can also reorder instructions by using out-of-order execution if it believes it makes things faster this way without ‘asking’ or ‘telling’ the programmer or the OS, so you might not have any guarantee that A happens before B.

处理器也可以通过使用乱序执行来重新排序指令,如果它认为这样做可以让事情更快,而不需要“询问”或“告诉”程序员或操作系统,所以你可能无法保证A在B之前发生。

The CPU offloads some work to separate ‘coprocessors’ such as the FPU for floating-point calculations, leaving the main CPU ready to do other tasks et cetera.

CPU将一些工作卸载给独立的“协处理器”,比如FPU进行浮点计算,让主CPU准备好做其他任务等等。

As a high-level overview, it’s OK to model the CPU as operating in a synchronous manner, but for now, let’s just make a mental note that this is a model with some caveats that become especially important when talking about parallelism, synchronization primitives (such as mutexes and atomics), and the security of computers and operating systems.

作为一个高级概述,将CPU建模为以同步方式操作是可以的,但是现在,让我们记住,这个模型带有一些注意事项,在讨论并行性、同步原语(如互斥体和原子)以及计算机和操作系统的安全性时,这些注意事项变得特别重要。

相关文章:

  • 排序方法——堆排序
  • Qt实现窗口失去焦点抖动功能
  • 在 Kubesphere 中开启新一代云原生数仓 Databend
  • 基于51单片机的超声波测距—数码管显示
  • sqliteSQL基础
  • 理解lambda表达式
  • 在本地电脑中如何用命令操作远程服务器上的数据库
  • [力扣题解] 28. 找出字符串中第一个匹配项的下标
  • 【算法】模拟算法——Z字形变换(medium)
  • Python魔法之旅-魔法方法(08)
  • BearPi-HM Nano开发笔记
  • LiveWeb前端:深度解析与挑战应对
  • net语言编程:深入探索其奥秘与挑战
  • 说说影响网络的因素
  • Java网络编程(上)
  • 08.Android之View事件问题
  • 2018一半小结一波
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • canvas绘制圆角头像
  • exif信息对照
  • Golang-长连接-状态推送
  • Javascript弹出层-初探
  • Rancher-k8s加速安装文档
  • Traffic-Sign Detection and Classification in the Wild 论文笔记
  • Yii源码解读-服务定位器(Service Locator)
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 小程序01:wepy框架整合iview webapp UI
  • 用 vue 组件自定义 v-model, 实现一个 Tab 组件。
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • Spring第一个helloWorld
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • !!java web学习笔记(一到五)
  • #git 撤消对文件的更改
  • (JSP)EL——优化登录界面,获取对象,获取数据
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (Redis使用系列) Springboot 整合Redisson 实现分布式锁 七
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (每日持续更新)jdk api之StringBufferInputStream基础、应用、实战
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (一)spring cloud微服务分布式云架构 - Spring Cloud简介
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • ... 是什么 ?... 有什么用处?
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .htaccess 强制https 单独排除某个目录
  • .net企业级架构实战之7——Spring.net整合Asp.net mvc
  • .NET中winform传递参数至Url并获得返回值或文件
  • /ThinkPHP/Library/Think/Storage/Driver/File.class.php  LINE: 48
  • @GlobalLock注解作用与原理解析
  • @KafkaListener注解详解(一)| 常用参数详解
  • [ JavaScript ] JSON方法
  • [20171113]修改表结构删除列相关问题4.txt
  • [ACTF2020 新生赛]Upload 1
  • [ASP.NET 控件实作 Day7] 设定工具箱的控件图标