This article is rated Start-class on Wikipedia's content assessment scale. It is of interest to the following WikiProjects: | |||||||||||||||||||||||||||||||||||||
|
2007 comments
editNo need to paste the ENTIRE "No Silver Bullet" article here! I deleted it as it takes up space unnecessarily and, besides, it is linked in the references section of the Wikipedia article. We need this space to discuss the actual Wikipedia article. Thanks. 82.43.195.131 15:55, 16 October 2006 (UTC)
- The referenced article is now a dead link. I haven't checked archive.org but a mirror (of one of the early editions) can be found here http://worrydream.com/refs/Brooks-NoSilverBullet.pdf Wizard (talk) 02:01, 12 October 2023 (UTC)
I don't think the edits of 86.139.127.180 are in good faith. Example: "As frustrating as this may be, he is most probably right. Most of us are blub programmers." 69.156.156.191 21:17, 5 February 2007 (UTC)
Tenets in NSB
edit- Immediacy - enables one to maintain an overview of complexity. The slow turnaround of batch programming means that one inevitably forgets the minutiae, if not the very thrust, of what one was thinking when he stopped programming and called for compilation and execution. This interruption is costly in time, for one must refresh one s memory. The most serious effect may well be the decay of the grasp of all that is going on in a complex system. —Preceding unsigned comment added by 192.174.37.50 (talk) 23:43, 15 December 2009 (UTC)
swapped accidental and essential
editI think this interpretation is wrong: "It should be noted that Brooks states that this limitation to programmer productivity only applies to essential complexity and he advocated challenges to accidental complexity which he believes can lead to significant (perhaps greater than 10 fold in a 10 year period) improvements." I think brooks says that accidental (which is not meant as "by accident", but as "self made by developers") complexity was almost eliminated in the last few years (he makes this clear in the 1995 edition of the The Mythical Man-Month), but still there is no technique insight to improve the productivity of a software team by an order of magnitude it 10 years because we cannot tackle the essential complexity of the problems to be solved. Oderbolz 10:29, 14 October 2007 (UTC)
- I agree, that is totally backwards. I've swapped it around to "... advocated challenges to essential complexity...". --68.0.124.33 (talk) 21:28, 23 September 2008 (UTC)
Critics
editWhat about putting some information on critics of the article? Like this one: Why Software Is Bad and What We Can Do to Fix It
See also How to Construct 100% Bug-Free Software, also by Savain. He addresses specific claims by Brooks and how to handle essential complexity.
- Savain is not only a kook, but he has explicitly rejected the suggestion of submitting his ideas to a peer-reviewed journal. So it looks like his ideas are not only inadmissable into Wikipedia, they will always be so.—greenrd (talk) 16:05, 3 May 2010 (UTC)
- Ouch! I just read his blog, not only is he a kook, he is also very aggressive and insulting. Another weirdo with a blog. 200.114.149.47 (talk) 21:29, 24 August 2010 (UTC)
- Ad hominem arguments are not only useless and time wasting, they are a sign of cowardice.
I think this article shows well that Brooks paper is misunderstood by many. When Savain writes "No other paper in the annals of software engineering has had a more detrimental effect on humanity's efforts to find a solution to the software reliability crisis. Almost single-handedly, it succeeded in convincing the entire software development community that there is no hope in trying to find a solution." he fails to see that brooks writes from an optimistic position. Brooks admits that IT has seen a 6 order of magnitude improvement in performance, but he essentially says that the human problem will remain, no matter what technology we use. Also Savain says: " When Brooks wrote his famous paper, he apparently did not realize that his arguments applied only to algorithmic complexity." Brooks does not speak about a specific way to write software, his argument is valid for algorithmic or other software. For me, the most important part of brooks article is this: "I believe the hard part of building software to be the specification, design, and testing of this conceptual construct, not the labor of representing it and testing the fidelity of the representation. We still make syntax errors, to be sure; but they are fuzz compared with the conceptual errors in most systems." The problem is not a technical one (as Weinberg puts it: its always a people problem). Our rules and laws, our processes are complex, that is why it is hard to model them correctly. —Preceding unsigned comment added by Oderbolz (talk • contribs) 10:49, 14 October 2007 (UTC) \
- I don't think it's worthwhile to debate Savain's points. He is a kook. His arguments don't make sense, they are a mix of nonsensical statements and insults. 201.231.81.53 (talk) 04:54, 4 November 2011 (UTC)
Dubious
editThe "abridged" version of the "No Silver Bullet" article differs in more ways than length from other versions on the web. It makes some assertions that aren't in the others, and removes some text that would tend to contradict the new assertions. Finally, it appears to support notions about micropayment software licensing schemes that the author of the abridgement would personally profit from, and which were unlikely to have been considered seriously by the real Fred P. Brooks. I vote that it be removed or permanently marked as propagandized. 24.165.61.213 (talk) 08:08, 26 December 2007 (UTC)
DMC 13 Aug 2008
edit"Accidental Complexity" is easy to generate with one line of C++. This is a real example from production S3 code.
Keep in mind that since we pay BOM dollars for the CPU that runs this, every machine instruction literally costs the company money.
An "old school" method to set the machine width below might be "dMachineWidth = 20.0", and translate into 1 to 3 machine instructions. The code below translated into 96 instructions that we can see, and with calls into compiler functions probably makes the total overhead over 140 machine instructions.
The S3 code is: "CModel::Instance()->GetJob().GetJobStat().SetMachineWidth(dMachineWidth);"
First, a call is made to get the instance of the Model object, then a call to get the Job object, then a call to get the JobStat object, then finally a call to set the Machine Width.
Here's what the source looks like in machine code:
00023 8b 45 f8 mov eax, DWORD PTR _this$[ebp] 00026 dd 40 10 fld QWORD PTR [eax+16] 00029 d9 9d 30 ff ff ff fstp DWORD PTR tv94[ebp] 0002f d9 85 30 ff ff ff fld DWORD PTR tv94[ebp] 00035 51 push ecx 00036 d9 1c 24 fstp DWORD PTR [esp] 00039 e8 00 00 00 00 call ?Instance@CModel@@SAPAV1@XZ ; CModel::Instance 0003e 8b c8 mov ecx, eax 00040 e8 00 00 00 00 call ?GetJob@CModel@@QAEAAVJobProxy@@XZ ; CModel::GetJob 00045 8b c8 mov ecx, eax 00047 e8 00 00 00 00 call ?GetJobStat@JobProxy@@QAEAAVJobStat@@XZ ; JobProxy::GetJobStat 0004c 8b c8 mov ecx, eax 0004e e8 00 00 00 00 call ?SetMachineWidth@JobStat@@QAEXM@Z ; JobStat::SetMachineWidth
It contains the four calls, and those functions in turn are (beginning with "CModel::Instance()")
00000 55 push ebp 00001 8b ec mov ebp, esp 00003 81 ec c0 00 00 00 sub esp, 192 ; 000000c0H 00009 53 push ebx 0000a 56 push esi 0000b 57 push edi 0000c 8d bd 40 ff ff ff lea edi, DWORD PTR [ebp-192] 00012 b9 30 00 00 00 mov ecx, 48 ; 00000030H 00017 b8 cc cc cc cc mov eax, -858993460 ; ccccccccH 0001c f3 ab rep stosd 0001e b9 00 00 00 00 mov ecx, OFFSET ?instance@?1??Instance@CModel@@SAPAV2@XZ@4V2@A 00023 e8 00 00 00 00 call ??1CModel@@QAE@XZ ; CModel::~CModel 00028 5f pop edi 00029 5e pop esi 0002a 5b pop ebx 0002b 81 c4 c0 00 00 00 add esp, 192 ; 000000c0H 00031 3b ec cmp ebp, esp 00033 e8 00 00 00 00 call __RTC_CheckEsp 00038 8b e5 mov esp, ebp 0003a 5d pop ebp 0003b c3 ret 0
Note that at address 00023 and 00033 there are two calls to compiler functions. We have no idea how much overhead is there, but likely at least 20+ instructions per call, and perhaps many more.
Here's the GetJob() call:
00000 55 push ebp 00001 8b ec mov ebp, esp 00003 81 ec cc 00 00 00 sub esp, 204 ; 000000ccH 00009 53 push ebx 0000a 56 push esi 0000b 57 push edi 0000c 51 push ecx 0000d 8d bd 34 ff ff ff lea edi, DWORD PTR [ebp-204] 00013 b9 33 00 00 00 mov ecx, 51 ; 00000033H 00018 b8 cc cc cc cc mov eax, -858993460 ; ccccccccH 0001d f3 ab rep stosd 0001f 59 pop ecx 00020 89 4d f8 mov DWORD PTR _this$[ebp], ecx 00023 8b 45 f8 mov eax, DWORD PTR _this$[ebp] 00026 05 10 23 00 00 add eax, 8976 ; 00002310H 0002b 5f pop edi 0002c 5e pop esi 0002d 5b pop ebx 0002e 8b e5 mov esp, ebp 00030 5d pop ebp 00031 c3 ret 0
Now GetJobStat():
00000 55 push ebp 00001 8b ec mov ebp, esp 00003 81 ec cc 00 00 00 sub esp, 204 ; 000000ccH 00009 53 push ebx 0000a 56 push esi 0000b 57 push edi 0000c 51 push ecx 0000d 8d bd 34 ff ff ff lea edi, DWORD PTR [ebp-204] 00013 b9 33 00 00 00 mov ecx, 51 ; 00000033H 00018 b8 cc cc cc cc mov eax, -858993460 ; ccccccccH 0001d f3 ab rep stosd 0001f 59 pop ecx 00020 89 4d f8 mov DWORD PTR _this$[ebp], ecx 00023 8b 45 f8 mov eax, DWORD PTR _this$[ebp] 00026 05 4f 01 00 00 add eax, 335 ; 0000014fH 0002b 5f pop edi 0002c 5e pop esi 0002d 5b pop ebx 0002e 8b e5 mov esp, ebp 00030 5d pop ebp 00031 c3 ret 0
Finally! We set the machine width:
00000 55 push ebp 00001 8b ec mov ebp, esp 00003 81 ec cc 00 00 00 sub esp, 204 ; 000000ccH 00009 53 push ebx 0000a 56 push esi 0000b 57 push edi 0000c 51 push ecx 0000d 8d bd 34 ff ff ff lea edi, DWORD PTR [ebp-204] 00013 b9 33 00 00 00 mov ecx, 51 ; 00000033H 00018 b8 cc cc cc cc mov eax, -858993460 ; ccccccccH 0001d f3 ab rep stosd 0001f 59 pop ecx 00020 89 4d f8 mov DWORD PTR _this$[ebp], ecx
- 99
- m_Stat.fMachineWidthM = fWidth;
00023 8b 45 f8 mov eax, DWORD PTR _this$[ebp] 00026 d9 45 08 fld DWORD PTR _fWidth$[ebp] 00029 d9 58 3b fstp DWORD PTR [eax+59]
- 100
- }
0002c 5f pop edi 0002d 5e pop esi 0002e 5b pop ebx 0002f 8b e5 mov esp, ebp 00031 5d pop ebp 00032 c2 04 00 ret 4
That was one line of source code. The following are the next three lines:
CModel::Instance()->GetJob().GetJobStat().SetOverlap(dIntentionalOverlap); CModel::Instance()->GetJob().GetJobStat().SetAntOffset(fAntennaXOffset); CModel::Instance()->GetJob().UpdateStatModifiedTime();
Including the first line, the "Instance()->GetJob()" pair was called four times, and "GetJobStat()" three times, each time returning the same value. The total instructions for accomplishing four trivial tasks was no doubt over 500 machine instructions. But that could have been dramatically reduced had the "Instance()->GetJob()" been used to set a local pointer, and "GetJobStat()" the same, and then used those pointers to access the end functions.
Even better, if the relevant job class (no doubt only one exists at a time) been kept as a global pointer, then the machine instructions would have only been a fraction. But no doubt that's not a kosher method.
In my old-school ideal, these values would be global to the whole project and set here directly, probably resulting in 10 or so instructions, probably a 50x improvement in efficiency. The code for "Instance()", "GetJob()", "GetJobStat()", and the various "set" functions wouldn't have needed to be written or maintained. How all that extra code and complexity can possibly be a "better" way to write software I haven't a clue. Unnecessary complexity is never a good thing. —Preceding unsigned comment added by 208.77.60.70 (talk) 23:19, 13 August 2008 (UTC)
- That is not what brookes meant by accidental complexity. Brookes ignores the complexity the CPU has to deal with and cares primary about the complexity the programmer needs to worry about. Compare "walk forward one step" to "lift left foot; adjust balance; move left foot forward; adjust balance; put down left foot; adjust balance". Both programs have the same essential complexity (they both take one step forward) but the second has considerably more accidental complexity. The example you've given is a bit contrived, why are we not keeping pointers (in the local scope) to the start of our current job and the job itself? Thus what I dislike about the example is that it has accidental complexity we can get rid of (the redundent and repeated function calls). Even with that though I much prefer it to global vars and implicit data passing! Pcecificly if you disagree with OOP then I would encourage you to read Brooke's mythical man month, make sure it is the aniversary version with the extra chapters. I say this because I too did not "get" OOP until I read Brookes, specifically the chapter where he changes his opinion on data hiding.
Merge
editI don't see why we need 3 articles (two of which are stubs—well, one stub article and one stubby section in another) to discuss the distinction between accidental and essential complexity, as defined by Brooks in this paper. JMP EAX (talk) 08:53, 24 July 2014 (UTC)
- I agree, perhaps the other articles could become redirects? Unit158 (talk) 03:48, 31 July 2014 (UTC)
- Okay, I'm gonna do that. JMP EAX (talk) 06:10, 1 August 2014 (UTC)
- And Done. I've actually made a dab at essential complexity. There wasn't much material to actually merge here, although the phrasing might have been a little better in the former stubs... JMP EAX (talk) 07:02, 1 August 2014 (UTC)