有害的工作切换
When you're managing a team of programmers, one of the first things you have to learn to get right is task allocation. That's just a five-dollar word for giving people things to do. It's known colloquially as "file dumping" in Hebrew (because you dump files in peoples' laps). And how you decide which files to dump in which laps is one of the areas where you can get incredible productivity benefits if you do it right. Do it wrong, and you can create one of those gnarly situations where nobody gets anything accomplished and everybody complains that "nothing ever gets done around here."
Since this site is for programmers, I'm going to warm up your brains a little bit with a programming problem.
当你在管理一个程序员团队的时候, 要做对的第一件事情当然就是分配任务。 当然那只是给大家事做的复杂表述。 希伯莱语里的口语化说法就是“倒文件”。 如果做的好的话,决定哪个文件倒到那个圈里面对于获得最大的工作效率有着至关重要的决定作用。 做得不好, 那么你就会造成那种极端情况下的局面,没人完成手头的任务而且每个人都抱怨说“这儿什么事都办不成”。
当然这个网站的读者主要是程序员, 我接下来用个编程题给大家的大脑热热身。
Suppose you have two separate computations to perform, A and B. Each computation requires 10 seconds of CPU time. You have one CPU which, for the sake of this problem, doesn't have anything else in the queue.
On our CPU, multitasking is optional. So you can either do these computations one after the other...
Sequential Processing
假设你有两个不同的运算要进行, A 和B。 每项计算都要花10秒钟CPU时间。 针对这个问题你只有一个CPU,队列里没有其他任何东西。
在我们的这种CPU设定下, 允许多任务。 所以你可以一个接一个的完成这些计算…
顺序处理
Computation A|Computation B
1 2 3 4 5 6 7 8 9 10|11 12 13 14 15 16 17 18 19 20
... or, you can multitask. If you multitask, on this particular CPU, tasks run for 1 second at a time, and a task switch takes no time at all.
Multitasking
…或者,你能多任务。 如果你多任务的话,在这个CPU上,任务每次运行1秒钟, 一次任务切换不花任何时间。
多任务
1 |2 |3 |4 |5 |6 |7 |8 |9 |10 |11 |12 |13 |14 |15 |16 |17 |18 |19 |20
Which would you rather do? Most people's gut reaction is that multitasking is better. In both cases, you have to wait 20 seconds to get both of your answers. But think about how long it takes to get the results to each computation.
你会选哪一种策略? 大多数人的直觉可能会觉得多任务更好。 在每种情况下, 你多要等20秒钟来获得答案。 但是想想看最后得到每个人物的计算结果花了多久。
In both cases, the results of Computation B (shown in blue) take 20 seconds to arrive. But look at Computation A. With multitasking, its results take 19 seconds to arrive... yet with sequential processing they are ready in only 10 seconds.
两种情况下, 计算B的结果花了20分钟。 但是在计算A,如果采用多任务,A的结果就要花19秒才能完成… 而在串行处理下只要10秒钟结果就出来了。
In other words, in this nice contrived example, the average time per computation is lower (15 seconds rather than 19.5 seconds) when you do sequential processing rather than multitasking. (Actually, it's not such a contrived example -- it's based on a real problem Jared had to solve at work).
换句话说,在这个很好的设计的例子下, 每个计算的平均时间要更低(15秒VS19.5秒)如果你用顺序处理而不是多任务处理的话。 ( 实际上, 这不是设计的很好的例子 – 这实际上是Jared工作的时候要处理的实际问题)。
Method | Computation A takes | Computation B takes | Average |
---|---|---|---|
Sequential | 10 seconds | 20 seconds | 15 |
Multitasking | 19 seconds | 20 seconds | 19.5 |
方法 | 计算A 消耗 | 计算B消耗 | Average |
---|---|---|---|
顺序 | 10 seconds | 20 seconds | 15 |
多任务 | 19 seconds | 20 seconds | 19.5 |
Earlier I said that "a task switch takes no time at all." Actually, on real CPUs, a task switch takes a little bit of time... basically enough time to save out the state of the CPU registers and load the CPU registers for the other task. Realistically, this is as close to negligible as possible. But to make life interesting, let's imagine that task switches take half a second. Now things look even worse:
前面我假设“工作切换根本不花费时间”。 在真正的CPU上,一次任务切换实际还是要花一点儿时间的… 基本上要足够的时间保存当前CPU寄存器状态然后为新的计算任务装载新的CPU寄存器。 实际上,这几乎可以忽略不计。 但是为了把这件事情整的更有趣一点,我们姑且假设一次任务切花要消耗半秒钟。 这时候事情就变得更糟了
Method | Computation A takes | Computation B takes | Average |
---|---|---|---|
Sequential | Sequential 10 seconds | 20 + 1 task switch = 20.5 seconds | 15.25 |
Multitasking | 19 + 18 task switches = 28 seconds | 20 + 19 task switches = 29.5 seconds | 28.75 |
Now ... just humor me, I know this is silly ... what if task switches take a whole minute?
然后…纯粹开玩笑, 我知道这听起来很傻… 如果任务切换要花费整整一分钟呢?
Method | Computation A takes | Computation B takes | Average |
---|---|---|---|
Sequential | Sequential 10 seconds | 20 + 1 task switch = 80 seconds | 45 |
Multitasking | 19 + 18 task switches = 1099 seconds | 20 + 19 task switches = 1160 seconds | 19minutes |
The longer a task switch takes, the worse the multitasking penalty.
That, in and of itself, is not so earth shaking, is it? Pretty soon I'm going to be getting irate email from morons accusing me of being "against" multitasking. "Do you want to go back to the days of DOS when you had to exit WordPerfect to run 1-2-3?" they will ask me.
But that's not my point. I just want you to agree with me that in this kind of example:
任务切换花的时间按越长, 多任务的代价就越大。 这,究其本质来看,好像也没那么大不了的么,是么? 不久之后我就能收到愤怒的傻蛋发给我的邮件职责我“反对”多任务。 “你想回到DOS时代,先要关掉WordPerfect然后才能运行1-2-3么?” 他们会问我。 但那不是我想说的啊。 我只是想要你同意我以下的一些例子:
a) sequential processing gets you results faster on average, and
b) the longer it takes to task switch, the bigger the penalty you pay for multitasking.
a. 顺序处理让你更快的获得你要的结果,以及
b. 切换任务花费时间越长, 多任务处理的代价就越大
OK, back to the more interesting topic of managing humans, not CPUs. The trick here is that when you manage programmers, specifically, task switches take a really, really, really long time. That's because programming is the kind of task where you have to keep a lot of things in your head at once. The more things you remember at once, the more productive you are at programming. A programmer coding at full throttle is keeping zillions of things in their head at once: everything from names of variables, data structures, important APIs, the names of utility functions that they wrote and call a lot, even the name of the subdirectory where they store their source code. If you send that programmer to Crete for a three week vacation, they will forget it all. The human brain seems to move it out of short-term RAM and swaps it out onto a backup tape where it takes forever to retrieve.
好吧,忘掉CPU回到更有意思的管理人的话题上来吧。 技巧就是当你管理程序员的时候, 任务切换会花很长,很长,很长时间。 这是因为编程是一件需要你在大脑中一次同时放很多事情的任务。 你同时记住的事情越多,编起程序来就越有效率。 一个以全速编程的程序员脑袋里一下子记住了数以万亿计的东西: 从变量的名字,到数据结构,到重要的API,到他们自己编写的经常调用的工具函数的名字, 乃至他们存代码的子文件夹。 如果你把这个程序员送到克里特岛去度假三个礼拜, 他们就会全部忘记这些东西。 人类的大脑似乎把这些东西移出了短期的RAM然后换到了某个备份磁带上,但是似乎永远再也拿不回来了。
How long? Well, my software company recently dropped what we were doing (developing a software product codenamed CityDesk) to help a client with a bit of an emergency situation for three weeks. When we got back to the office, it seemed to take another three weeks to get back to full speed on CityDesk.
On the individual level -- have you ever noticed that you can assign one job to one person, and they'll do a great job, but if you assign twojobs to that person, they won't really get anything done? They'll either do one job well and neglect the other, or they'll do both jobs so slowly you feel like slugs have more zip. That's because programming tasks take so long to task switch. I feel like when I have two programming projects on my plate at once, the task switch time is something like 6 hours. In an 8-hour day, that means multitasking reduces my productivity to 2 hours per day. Pretty dismal.
要花多久才能再记起来? 恩, 我的软件公司最近放下了手头正在开发的(CityDesk软件)花三个礼拜来帮助一个客户处理一桩紧急的突发状况。 当我们回到办公室的时候, 似乎要再花3周回到全速开发CityDesk的状态。
就个人而言 – 你有没有注意到,如果你给一个人派一项工作,他们会干的很好, 但是如果你同时给一个人派两项工作,他们却啥都做不成? 他们要么做好了一项然后忽视另一项。 要么两项任务进展都超级慢,让你觉得蜗牛爬的还要快一点儿呢。 这是因为编程任务之间的切换要花很长时间。 我觉得如果我要是手头一下子有两个编程项目的话,那么任务切换大概要花6个小时。 一天8小时的话,意味着多任务将我的效率减为每天两个小时, 真惨。
As it turns out, if you give somebody two things to work on, you should be grateful if they "starve" one task and only work on one, because they're going to get more stuff done and finish the average task sooner. In fact, the real lesson from all this is that you should never let people work on more than one thing at once. Make sure they know what it is. Good managers see their responsibility as removing obstacles so that people can focus on one thing and really get it done. When emergencies come up, think about whether you can handle it yourself before you delegate it to a programmer who is deeply submersed in a project.
事实表明,如果你让某个人同时做两件事情的话, 你会很后悔的发现他们“搁置”一项任务然后只做另外一件。 因为这样他们才能做更多的事情然后,更快的完成每项任务。 实际上,这里想说的意思就是:你永远不应该让员工同时处理两件事情。 确保他们知道要做的是什么。 好的经理会看到自己的职责在于帮人们清除障碍这样大家就可以专注在一件事情上,然后完成这项任务。 当紧急情况出现的时候,你要在将其分配给其他正投入到某项任务中的程序员的时候想想自己是不是能处理。