计算机系统的设计原则

计算机系统的设计原则

你可能称之指南, 启发法, 或者经验法则. 这都无所谓, 目的是一样的 : 提供一哥近似合理的真想. 这些经验法则可以帮助你理解运行的系统, 使你专注于正确的事情, 重视潜在的问题区.

目录:

  1. General
  2. 设计
  3. 成本
  4. 任务
  5. 硬件
  6. 软件重用
  7. 优化
  8. 危险信号和危险区
  9. 中断
  10. 系统功能点规则
  11. 进一步阅读

通用

  • 保持系统正常运行比在中断系统后对其进行修复要容易得多。 (詹姆斯·格林宁)
  • 尽可能将错误从运行时转移到编译时
  • 没有文档的程序没有价值
  • 注释永远都不要重述代码的明显作用。
  • 注释应通过描述意图来辅助后期维护。
  • 头文件中的所有内容都应至少在两个源文件中使用
  • Developer productivity is dramatically increased by eliminating distractions and interrupts
    • “Developers who live in cubicles probably aren’t very productive. Check how they manage interruptions.” (Jack Ganssle)
  • “Complexity grows exponentially; Robert Glass figures for every 25% increase in the problem’s difficulty the code doubles in size. A many-million line program can assume a number of states whose size no human can grasp.” (Jack Ganssle)
  • In nature, the optimum is almost always in the middle somewhere. Distrust assertions that the optimum is at an extreme point. (Akin’s Laws)
  • Past experience is excellent for providing a reality check. Too much reality can doom an otherwise worthwhile design, though (Akin’s Laws)
  • As a rule of thumb, every hour you spend on defect prevention will reduce your repair time from three to ten hours. (Steve McConnell)

设计

  • 复杂的系统由有效的简单系统演变而来(John Gall)
    • “A complex system that works is invariably found to have evolved from a simple system that worked. The inverse proposition also appears to be true: A complex system designed from scratch never works and cannot be made to work. You have to start over, beginning with a working simple system.” (John Gall)
  • If you can’t describe the behavior in plain English, you can’t successfully describe it with code
  • Decompose complex problems into smaller sub-problems
    • If a problem can be decomposed into two or more independently solvable problems, then solve them independently first!
    • After you have implemented and tested the solutions, combine the parts into a larger operation
  • 一个功能应仅执行一项概念性任务
  • 不要解决不存在的问题
  • 解决特定问题,而不是一般情况
  • To design a spacecraft right takes an infinite amount of effort. This is why it’s a good idea to design them to operate when some things are wrong. (Akin’s Laws)
  • Design is an iterative process. The necessary number of iterations is one more than the number you have currently done. This is true at any point in time. (Akin’s Laws)
  • There is never a single right solution. There are always multiple wrong ones, though. (Akin’s Laws)
  • (Edison’s Law) “Better” is the enemy of “good”. (Akin’s Laws)
  • (Shea’s Law) The ability to improve a design occurs primarily at the interfaces. This is also the prime location for screwing it up. (Akin’s Laws)
  • Studies have found that reworking defective requirements, design, and code typically consumes 40 to 50 percent of the total cost of software development. (Steve McConnell, citing Capers Jones)
    • 在最坏的情况下,一旦软件投入运行,重新处理软件需求问题的成本通常是在需求阶段重新处理问题的成本的50到200倍。 (史蒂夫·麦康奈尔(Steve McConnell)引用Boehm和Papaccio的话)

成本

  • 软件昂贵
    • “经过研究后的研究表明,在未记录的混乱情况中,商业代码的价格为每行15至30美元。 糟糕的1000行代码(很难在1000行中完成很多工作)的实际成本约为30,000美元。 老字眼看到的“这仅仅是软件的变化”相当于“这只是一块金砖”。 (杰克·甘斯勒)
    • “The answer is $15 to $40 per line of code. At the $40 end you can get relatively robust, well designed code suitable for industry applications. The $15 end tends to be code with skimpy design packages and skimpy testing. (In other words, some people spend only $15/line, but their code is of doubtful quality.)” (Phil Koopman)
    • “更新,2015年10月。现在,每行代码可能更像是$ 25- $ 50。 外包给亚洲的项目的成本急剧上升,因为工资和稀缺编码员的竞争加剧了。” (菲尔·考夫曼)
  • 如果您想减少软件开发成本,请查看每个需求文档并粗暴地删除功能。 (杰克·甘斯勒)
    • 许多功能等于进度缓慢且开发成本昂贵(Jack Ganssle)
  • Non-recurring engineering (NRE) costs must be amortized over every product sold
    • Save NRE dollars by reducing features
    • Save NRE dollars by offloading software functionality into hardware components (increases BOM cost)
      • Only useful if that hardware already exists!
      • Software/hardware partitioning should be assessed early in the design process
    • Save NRE dollars by delivering the product faster (Jack Ganssle)
  • It is easier and cheaper to completely rewrite the 5% of problematic functions than to fix the existing implementation
    • These functions cost four times as much as other functions (Barry Boehm)
    • “也许我们在初次编写代码时确实感到很震惊,但是如果我们能够识别出这些糟糕的例程,把它们扔掉,然后重新开始,那么我们将节省很多钱。” (杰克·甘斯勒)

任务

  • 永远没有足够的时间来正确地做它,但是总有足够的时间来完成它。 (阿金法则)
  • Estimating dates instead of hours guarantees a late project (Jack Ganssle)
    • “Scheduling disasters are inevitable when developers don’t separate calendar time from engineering hours.” (Jack Ganssle)
  • “If the schedule hallucinates a people-utilization factor of much over 50% the project will be behind proportionately.” (Jack Ganssle)
    • “Some data suggests the average developer is only about 55% engaged on new product work. Other routine activities, from handling paperwork to talking about Survivor XVI, burn almost half the work week.” (Jack Ganssle)
  • We often fail to anticipate the difficult areas of development
    • “Isn’t it amazing how badly we estimate schedules for most projects? 80% of embedded systems are delivered late. Most pundits figure the average project consumes twice the development effort originally budgeted.” (Jack Ganssle)
  • 5% of functions consume 80% of debugging time (Jack Ganssle)
    • “I’ve observed that most projects wallow in the debug cycle, which often accounts for half of the entire schedule. Clearly, if we can do something about those few functions that represent most of our troubles, the project will get out the door that much sooner.” (Jack Ganssle)
  • Timelines grow much faster than firmware size – double the lines of code, and the delivery date increases by more than 2x (Barry Boehm)
  • “代码的前90%占了开发时间的前90%。 剩下的10%的代码占了开发时间的90%。” (汤姆·嘉吉)
  • When porting old code to a new project, if more than about 25% gets modified there’s not much of a schedule boost (Richard Selby)
  • Systems loaded to 90% of the processor capability require 2x development time over systems loaded at 70% or less. 95% loading triples development time. (Jack Ganssle)
    • “When only a few bytes are left, even trivial features can take weeks as developers must rewrite massive sections of code to free up memory or CPU cycles.” (Jack Ganssle)
  • 您制定的时间表似乎是虚构的完整作品,直到您的客户因不满足而解雇您为止。 (阿金法则)
  • Sometimes, the fastest way to get to the end is to throw everything out and start over. (Akin’s Laws)
  • (帕顿的程序规划法则)现在猛烈执行的好的计划比下周的完善计划要好。 (阿金法则)

硬件

  • 添加硬件会增加电源要求
  • Use of hardware accelerators to offload CPU-based algorithms can reduce power requirements
  • Every sensor is a temperature sensor. Some sensors measure other things as well. (Elecia White)
  • Break out nasty real-time hardware functions into independent CPUs (Jack Ganssle)
    • Handling 1000 interrupts per second from a device? Partition it to its own controller and offload all of the ISR overhead off of the main processor
  • Add hardware whenever it can simplify the software (Jack Ganssle)
    • This will dramatically reduce NRE and software development costs, at a tradeoff for an increase in BOM costs.
    • Systems loaded to 90% of the processor capability require 2x development time over systems loaded at 70% or less. 95% loading triples development time. Add additional hardware to reduce loading. (Jack Ganssle)
  • (阿特金示范法则)当硬件运行正常时,真正重要的访客不会出现。 (阿金法则)

软件重用

  • 优先使用已被其他人重复使用的现有经过审查的代码
    • 例如 使用STL而不是编写自己的容器
  • Prefer simple, standard communication protocols over custom communication protocols
  • Follow the “Rule of Three”: you are allowed to copy and paste the code once, but that when the same code is replicated three times, it should be extracted into a new procedure (Martin Fowler)
  • Before a package is truly reusable, it must have been reused at least three times (Jack Ganssle)
    • “We’re not smart enough to truly understand the range of applications where a chunk of software may be used. Every domain requires its own unique features and tweaks; till we’ve actually used the code several times, over a wide enough range of apps, we won’t have generalized it enough to have it truly reusable.” (Jack Ganssle)
  • 重用最好在大部分代码中完成–考虑重用整个驱动程序或库,而不是重用功能(Jack Ganssle)

优化

  • 过早的优化浪费时间
    • “More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason — including blind stupidity.” (W.A. Wulf)
    • “The First Rule of Program Optimization: Don’t do it. The Second Rule of Program Optimization (for experts only!): Don’t do it yet.” (Michael A. Jackson)
  • Only optimize code after you have profiled it to identify the problem area
    • “Bottlenecks occur in surprising places, so don’t try to second guess and put in a speed hack until you have proven that’s where the bottleneck is.” (Rob Pike)
    • “We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has been identified” (Donald Knuth)
  • The Pareto principle can be applied to resource optimization: 80% of resources are used by 20% of operations
    • Alternatively, there is the 90/10 law in software engineering: 90% of the execution time of a program is spent executing 10% of the code
  • Algorithmic optimizations have a greater impact than micro optimizations
    • “Real efficiency gains come from changing the order of complexity of the algorithm, such as changing from O(N2) to O(NlogN) complexity”
  • 切勿为了获得感知的效率而牺牲清晰度,尤其是在没有数据证明效率提高的情况下

危险信号和危险区

  • 当开发人员害怕更改功能时,是时候从头开始重写该代码了(Jack Ganssle)
  • Duplicate code is an indication of poor design or poor programming habits. It must be eliminated.
    • “Duplication is a bad practice because it makes code harder to maintain. When the rule encoded in a replicated piece of code changes, whoever maintains the code will have to change it in all places correctly. This process is error-prone and often leads to problems. If the code exists in only one place, then it can be easily changed there.” (Jack Ganssle)
    • “This rule is can even be applied to small number of lines of code, or even single lines of code. For example, if you want to call a function, and then call it again when it fails, it’s OK to have two call sites; however, if you want to try it five times before giving up, there should only be one call site inside a loop rather than 5 independent calls.” (Jack Ganssle)
  • Avoid shared resources wherever possible (Jack Ganssle)
  • Eliminate globals!
  • Disabling interrupts tends to be A Bad Thing (Jack Ganssle)
    • Even in the best of cases it’ll increase system latency and probably decrease performance
    • Increased latency leads to missed interrupts and mismanaged devices
  • Be wary of solo Enable Interrupt (EI) commands (Jack Ganssle)
    • “An EI located outside an interrupt service routine (ISR) often suggests peril – with the exception of the initial EI in the startup code.” (Jack Ganssle)
    • “When the enable is not part of a DI/EI pair (and these two instructions must be very close to each other to keep latency down and maintainability up) then the code is likely a convoluted, cryptic well; plumbing these depths will age the most eager of developers.” (Jack Ganssle)
  • Be wary when code is peppered with DI/EI Pairs (Jack Ganssle)
    • Excessive use of Disable Interrupt instructions suggests poor design
    • “但是,当出现系统性设计问题时,这些DI / EI对会大量渗入代码,从而产生许多容易出现折返问题的关键区域。 您知道这是怎么回事:勇敢的开发人员追逐错误,发现上下文切换破坏了变量。 弹出快速DI / EI对。 然后还有另一个。 还有一个。 就像是海洛因使用者遭受了最后一击。 它永远不会结束。” (杰克·甘斯勒)

中断

  • 在最短的时间内和最迫切的需求中,保持中断。 (杰克·甘斯勒)
  • If you disable interrupts in a block of code, re-enable them in the same block (Jack Ganssle)
  • Keep ISRs small
    • Be wary of ISRs longer than half a page of code (Jack Ganssle)
    • In most cases, there should be little-to-no processing inside of the handler (Phillip Johnston)
    • Set a flag, add a value to a queue, and then rely on user-space code to handle more complex tasks
  • Minimize ISR latency to ensure the system does not miss interrupts (Jack Ganssle)
  • Check the design of any ISR that reenables interrupts immediately before returning (Jack Ganssle)
    • Minimize critical sections within the ISR.
    • “允许其他设备中断ISR很好! 给定足够的堆栈空间,甚至允许相同的中断执行此操作。 这表明我们应该创建服务例程,以尽早处理所有非可重入任务(例如维修硬件),发布EI,然后继续可重入活动。 然后弹出寄存器并返回。” (杰克·甘斯勒)

避免在中断处理程序中执行以下操作:(Phillip Johnston)

  • Don’t declare any non-static variables inside the handler
  • Avoid blocking function calls
  • Avoid non-reentrant function calls
  • Avoid any processing that takes non-trivial time
  • Avoid operations with locks as you can deadlock your program in an ISR
  • Avoid operations that involve dynamic memory allocations, as the allocation may require a lock and will take a non-determinate amount of time
  • Avoid stack allocations
    • 根据您的体系结构和操作模型,您的中断处理程序可能会使用被中断线程的堆栈或常见的“中断堆栈”。

功能点经验法则

功能点是软件一部分功能的度量,您可以在此处阅读。 一个C功能点平均大约需要130行代码。

这是Capers的经验法则,“ FP” 表示功能点。 这些摘自杰克·甘斯勒(Jack Ganssle)的时事通讯。

  • Approximate number of bugs injected in a project: FP1.25
    • Manual code inspections will find about 65% of the bugs. The number is much higher for very disciplined teams.
  • Number of people on the project is about: FP/150
  • Approximate page count for paper documents associated with a project: FP1.15
  • Each test strategy will find about 30% of the bugs that exist.
  • The schedule in months is about: FP0.4
  • Full time number of people required to maintain a project after release: FP/750
  • Requirements grow about 2%/month from the design through coding phases.
  • 将创建的测试用例的大致数量:FP1.2

进一步阅读

变更日志

  • 20200602:
    • Removed duplicate entry
  • 20200311:
    • Added additional rules of thumb
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值