深入理解計算機系統(英文版·第3版)

《深入理解計算機系統(英文版·第3版)》是2017年機械工業出版社出版圖書,作者[美] 蘭德爾 E.布萊恩特(Randal E. Bryant)大衛 R. 奧哈拉倫(David R. O'Hallaron)。

出版信息

作者:[美] 蘭德爾 E.布萊恩特(Randal E. Bryant)大衛 R. 奧哈拉倫(David R. O'Hallaron) 著
ISBN(書號):978-7-111-56127-9
叢書名:經典原版書庫
出版日期:2017-04
版次:1/1
開本:16
定價:¥239.00

內容簡介

本書是一本將計算機軟體和硬體理論結合講述的經典教材,內容涵蓋計算機導論、體系結構和處理器設計等多門課程。本書最大的特點是為程式設計師描述計算機系統的實現細節,通過描述程式是如何映射到系統上,以及程式是如何執行的,使讀者更好地理解程式的行為,找到程式效率低下的原因。
和第2版相比,本版內容上最大的變化是,從以IA32和x86-64為基礎轉變為完全以x86-64為基礎。主要更新如下:
· 基於x86-64,大量地重寫代碼,首次介紹對處理浮點數據的程式的機器級支持。
· 處理器體系結構修改為支持64位字和操作的設計。
· 引入更多的功能單元和更複雜的控制邏輯,使基於程式數據流表示的程式性能模型預測更加可靠。
· 擴充關於用GOT和PLT創建與位置無關代碼的討論,描述了更加強大的連結技術(比如庫打樁)。
· 增加了對信號處理程式更細緻的描述,包括異步信號安全的函式等。
· 採用最新函式,更新了與協定無關和執行緒安全的網路編程。

圖書目錄

Preface xix About the Authors xxxv

1

A Tour of Computer Systems 1

1.1 Information Is Bits + Context 3

1.2 Programs Are Translated by Other Programs into Different Forms 4

1.3 It Pays to Understand How Compilation Systems Work 6

1.4 Processors Read and Interpret Instructions Stored in Memory 7

1.4.1 Hardware Organization of a System 8

1.4.2 Running the helloProgram 10

1.5 Caches Matter 11

1.6 Storage Devices Form a Hierarchy 14

1.7 The Operating System Manages the Hardware 14

1.7.1 Processes 15

1.7.2 Threads 17

1.7.3 Virtual Memory 18

1.7.4 Files 19

1.8 Systems Communicate with Other Systems Using Networks 19

1.9 Important Themes 22

1.9.1 Amdahl’s Law 22

1.9.2 Concurrency and Parallelism 24

1.9.3 The Importance of Abstractions in Computer Systems 26

1.10 Summary 27 Bibliographic Notes 28 Solutions to Practice Problems 28

Part I Program Structure and Execution

2

Representing and Manipulating Information 31

2.1 Information Storage 34

2.1.1 Hexadecimal Notation 36

2.1.2 Data Sizes 39

2.1.3 Addressing and Byte Ordering 42

2.1.4 Representing Strings 49

2.1.5 Representing Code 49

2.1.6 Introduction to Boolean Algebra 50

2.1.7 Bit-Level Operations in C 54

2.1.8 Logical Operations in C 56

2.1.9 Shift Operations in C 57

2.2 Integer Representations 59

2.2.1 Integral Data Types 60

2.2.2 Unsigned Encodings 62

2.2.3 Two’s-Complement Encodings 64

2.2.4 Conversions between Signed and Unsigned 70

2.2.5 Signed versus Unsigned in C 74

2.2.6 Expanding the Bit Representation of a Number 76

2.2.7 Truncating Numbers 81

2.2.8 Advice on Signed versus Unsigned 83

2.3 Integer Arithmetic 84

2.3.1 Unsigned Addition 84

2.3.2 Two’s-Complement Addition 90

2.3.3 Two’s-Complement Negation 95

2.3.4 Unsigned Multiplication 96

2.3.5 Two’s-Complement Multiplication 97

2.3.6 Multiplying by Constants 101

2.3.7 Dividing by Powers of 2 103

2.3.8 Final Thoughts on Integer Arithmetic 107

2.4 Floating Point 108

2.4.1 Fractional Binary Numbers 109

2.4.2 IEEE Floating-Point Representation 112

2.4.3 Example Numbers 115

2.4.4 Rounding 120

2.4.5 Floating-Point Operations 122

2.4.6 Floating Point in C 124

2.5 Summary 126

Bibliographic Notes 127

Homework Problems 128

Solutions to Practice Problems 143

3

Machine-Level Representation of Programs 163

3.1 A Historical Perspective 166

3.2 Program Encodings 169

3.2.1 Machine-Level Code 170

3.2.2 Code Examples 172

3.2.3 Notes on Formatting 175

3.3 Data Formats 177

3.4 Accessing Information 179

3.4.1 Operand Speci.ers 180

3.4.2 Data Movement Instructions 182

3.4.3 Data Movement Example 186

3.4.4 Pushing and Popping Stack Data 189

3.5 Arithmetic and Logical Operations 191

3.5.1 Load Effective Address 191

3.5.2 Unary and Binary Operations 194

3.5.3 Shift Operations 194

3.5.4 Discussion 196

3.5.5 Special Arithmetic Operations 197

3.6 Control 200

3.6.1 Condition Codes 201

3.6.2 Accessing the Condition Codes 202

3.6.3 Jump Instructions 205

3.6.4 Jump Instruction Encodings 207

3.6.5 Implementing Conditional Branches withConditional Control 209

3.6.6 Implementing Conditional Branches withConditional Moves 214

3.6.7 Loops 220

3.6.8 Switch Statements 232

3.7 Procedures 238

3.7.1 The Run-Time Stack 239

3.7.2 Control Transfer 241

3.7.3 Data Transfer 245

3.7.4 Local Storage on the Stack 248

3.7.5 Local Storage in Registers 251

3.7.6 Recursive Procedures 253

3.8 Array Allocation and Access 255

3.8.1 Basic Principles 255

3.8.2 Pointer Arithmetic 257

3.8.3 Nested Arrays 258

3.8.4 Fixed-Size Arrays 260

3.8.5 Variable-Size Arrays 262

3.9 Heterogeneous Data Structures 265

3.9.1 Structures 265

3.9.2 Unions 269

3.9.3 Data Alignment 273

3.10 Combining Control and Data in Machine-Level Programs 276

3.10.1 Understanding Pointers 277

3.10.2 Life in the Real World: Using the gdbDebugger 279

3.10.3 Out-of-Bounds Memory References and Buffer Over.ow 279

3.10.4 Thwarting Buffer Over.ow Attacks 284

3.10.5 Supporting Variable-Size Stack Frames 290

3.11 Floating-Point Code 293

3.11.1 Floating-Point Movement and Conversion Operations 296

3.11.2 Floating-Point Code in Procedures 301

3.11.3 Floating-Point Arithmetic Operations 302

3.11.4 De.ning and Using Floating-Point Constants 304

3.11.5 Using Bitwise Operations in Floating-Point Code 305

3.11.6 Floating-Point Comparison Operations 306

3.11.7 Observations about Floating-Point Code 309

3.12 Summary 309

Bibliographic Notes 310

Homework Problems 311

Solutions to Practice Problems 325

4

Processor Architecture 351

4.1 The Y86-64 Instruction Set Architecture 355

4.1.1 Programmer-Visible State 355

4.1.2 Y86-64 Instructions 356

4.1.3 Instruction Encoding 358

4.1.4 Y86-64 Exceptions 363

4.1.5 Y86-64 Programs 364

4.1.6 Some Y86-64 Instruction Details 370

4.2 Logic Design and the Hardware Control Language HCL 372

4.2.1 Logic Gates 373

4.2.2 Combinational Circuits and HCL Boolean Expressions 374

4.2.3 Word-Level Combinational Circuits and HCLInteger Expressions 376

4.2.4 Set Membership 380

4.2.5 Memory and Clocking 381

4.3 Sequential Y86-64 Implementations 384

4.3.1 Organizing Processing into Stages 384

4.3.2 SEQ Hardware Structure 396

4.3.3 SEQ Timing 400

4.3.4 SEQ Stage Implementations 404

4.4 General Principles of Pipelining 412

4.4.1 Computational Pipelines 412

4.4.2 A Detailed Look at Pipeline Operation 414

4.4.3 Limitations of Pipelining 416

4.4.4 Pipelining a System with Feedback 419

4.5 Pipelined Y86-64 Implementations 421

4.5.1 SEQ+: Rearranging the Computation Stages 421

4.5.2 Inserting Pipeline Registers 422

4.5.3 Rearranging and Relabeling Signals 426

4.5.4 Next PC Prediction 427

4.5.5 Pipeline Hazards 429

4.5.6 Exception Handling 444

4.5.7 PIPE Stage Implementations 447

4.5.8 Pipeline Control Logic 455

4.5.9 Performance Analysis 464

4.5.10 Un.nished Business 468

4.6 Summary 470

4.6.1 Y86-64 Simulators 472

Bibliographic Notes 473

Homework Problems 473

Solutions to Practice Problems 480

5

Optimizing Program Performance 495

5.1 Capabilities and Limitations of Optimizing Compilers 498

5.2 Expressing Program Performance 502

5.3 Program Example 504

5.4 Eliminating Loop Inef.ciencies 508

5.5 Reducing Procedure Calls 512

5.6 Eliminating Unneeded Memory References 514

5.7 Understanding Modern Processors 517

5.7.1 Overall Operation 518

5.7.2 Functional Unit Performance 523

5.7.3 An Abstract Model of Processor Operation 525

5.8 Loop Unrolling 531

5.9 Enhancing Parallelism 536

5.9.1 Multiple Accumulators 536

5.9.2 Reassociation Transformation 541

5.10 Summary of Results for Optimizing Combining Code 547

5.11 Some Limiting Factors 548

5.11.1 Register Spilling 548

5.11.2 Branch Prediction and Misprediction Penalties 549

5.12 Understanding Memory Performance 553

5.12.1 Load Performance 554

5.12.2 Store Performance 555

5.13 Life in the Real World: Performance Improvement Techniques 561

5.14 Identifying and Eliminating Performance Bottlenecks 562

5.14.1 Program Pro.ling 562

5.14.2 Using a Pro.ler to Guide Optimization 565

5.15 Summary 568

Bibliographic Notes 569

Homework Problems 570

Solutions to Practice Problems 573

6

The Memory Hierarchy 579

6.1 Storage Technologies 581

6.1.1 Random Access Memory 581

6.1.2 Disk Storage 589

6.1.3 Solid State Disks 600

6.1.4 Storage Technology Trends 602

6.2 Locality 604

6.2.1 Locality of References to Program Data 606

6.2.2 Locality of Instruction Fetches 607

6.2.3 Summary of Locality 608

6.3 The Memory Hierarchy 609

6.3.1 Caching in the Memory Hierarchy 610

6.3.2 Summary of Memory Hierarchy Concepts 614

6.4 Cache Memories 614

6.4.1 Generic Cache Memory Organization 615

6.4.2 Direct-Mapped Caches 617

6.4.3 Set Associative Caches 624

6.4.4 Fully Associative Caches 626

6.4.5 Issues with Writes 630

6.4.6 Anatomy of a Real Cache Hierarchy 631

6.4.7 Performance Impact of Cache Parameters 631

6.5 Writing Cache-Friendly Code 633

6.6 Putting It Together: The Impact of Caches on Program Performance 639

6.6.1 The Memory Mountain 639

6.6.2 Rearranging Loops to Increase Spatial Locality 643

6.6.3 Exploiting Locality in Your Programs 647

6.7 Summary 648

Bibliographic Notes 648

Homework Problems 649

Solutions to Practice Problems 660

Part II Running Programs on a System

7

Linking 669

7.1 Compiler Drivers 671

7.2 Static Linking 672

7.3 Object Files 673

7.4 Relocatable Object Files 674

7.5 Symbols and Symbol Tables 675

7.6 Symbol Resolution 679

7.6.1 How Linkers Resolve Duplicate Symbol Names 680

7.6.2 Linking with Static Libraries 684

7.6.3 How Linkers Use Static Libraries to Resolve References 688

7.7 Relocation 689

7.7.1 Relocation Entries 690

7.7.2 Relocating Symbol References 691

7.8 Executable Object Files 695

7.9 Loading Executable Object Files 697

7.10 Dynamic Linking with Shared Libraries 698

7.11 Loading and Linking Shared Libraries from Applications 701

7.12 Position-Independent Code (PIC) 704

7.13 Library Interpositioning 707

7.13.1 Compile-Time Interpositioning 708

7.13.2 Link-Time Interpositioning 708

7.13.3 Run-Time Interpositioning 710

7.14 Tools for Manipulating Object Files 713

7.15 Summary 713

Bibliographic Notes 714

Homework Problems 714

Solutions to Practice Problems 717

第8章 異常控制流 721

8.1 異常 723

8.1.1 異常處理 724

8.1.2 異常的類別 726

8.1.3 Linux/x86-64系統中的異常 729

8.2 進程 732

8.2.1 邏輯控制流 732

8.2.2 並發流 733

8.2.3 私有地址空間 734

8.2.4 用戶模式和核心模式 734

8.2.5 上下文切換 736

8.3 系統調用錯誤處理 737

8.4 進程控制 738

8.4.1 獲取進程ID 739

8.4.2 創建和終止進程 739

8.4.3 回收子進程 743

8.4.4 讓進程休眠 749

8.4.5 載入並運行程式 750

8.4.6 利用fork和execve運行程式 753

8.5 信號 756

8.5.1 信號術語 758

8.5.2 傳送信號 759

8.5.3 接收信號 762

8.5.4 阻塞和解除阻塞信號 764

8.5.5 編寫信號處理程式 766

8.5.6 同步流以避免討厭的並發錯誤 776

8.5.7 顯式地等待信號 778

8.6 非本地跳轉 781

8.7 操作進程的工具 786

8.8 小結 787

參考文獻說明 787

家庭作業 788

練習題答案 795

第9章 虛擬記憶體 801

9.1 物理和虛擬定址 803

9.2 地址空間 804

9.3 虛擬記憶體作為快取的工具 805

9.3.1 DRAM快取的組織結構 806

9.3.2 頁表 806

9.3.3 頁命中 808

9.3.4 缺頁 808

9.3.5 分配頁面 810

9.3.6 又是局部性救了我們 810

9.4 虛擬記憶體作為記憶體管理的工具 811

9.5 虛擬記憶體作為記憶體保護的工具 812

9.6 地址翻譯 813

9.6.1 結合高速快取和虛擬記憶體 817

9.6.2 利用TLB加速地址翻譯 817

9.6.3 多級頁表 819

9.6.4 綜合:端到端的地址翻譯 821

9.7 案例研究:Intel Core i7/Linux記憶體系統 825

9.7.1 Core i7地址翻譯 826

9.7.2 Linux虛擬記憶體系統 828

9.8 記憶體映射 833

9.8.1 再看共享對象 833

9.8.2 再看fork函式 836

9.8.3 再看execve函式 836

9.8.4 使用mmap函式的用戶級記憶體映射 837

9.9 動態記憶體分配 839

9.9.1 malloc和free函式 840

9.9.2 為什麼要使用動態記憶體分配 843

9.9.3 分配器的要求和目標 844

9.9.4 碎片 846

9.9.5 實現問題 846

9.9.6 隱式空閒鍊表 847

9.9.7 放置已分配的塊 849

9.9.8 分割空閒塊 849

9.9.9 獲取額外的堆記憶體 850

9.9.10 合併空閒塊 850

9.9.11 帶邊界標記的合併 851

9.9.12 綜合:實現一個簡單的分配器 854

9.9.13 顯式空閒鍊表 862

9.9.14 分離的空閒鍊表 863

9.10 垃圾收集 865

9.10.1 垃圾收集器的基本知識 866

9.10.2 Mark&Sweep垃圾收集器 867

9.10.3 C程式的保守Mark&Sweep 869

9.11 C程式中常見的與記憶體有關的錯誤 870

9.11.1 間接引用壞指針 870

9.11.2 讀未初始化的記憶體 871

9.11.3 允許棧緩衝區溢出 871

9.11.4 假設指針和它們指向的對象是相同大小的 872

9.11.5 造成錯位錯誤 872

9.11.6 引用指針,而不是它所指向的對象 873

9.11.7 誤解指針運算 873

9.11.8 引用不存在的變數 874

9.11.9 引用空閒堆塊中的數據 874

9.11.10 引起記憶體泄漏 875

9.12 小結 875

參考文獻說明 876

家庭作業 876

練習題答案 880

第三部分

程式間的互動和通信

第10章 系統級I/O 889

10.1 Unix I/O 890

10.2 檔案 891

10.3 打開和關閉檔案 893

10.4 讀和寫檔案 895

10.5 用RIO包健壯地讀寫 897

10.5.1 RIO的無緩衝的輸入輸出函式 897

10.5.2 RIO的帶緩衝的輸入函式 898

10.6 讀取檔案元數據 903

10.7 讀取目錄內容 905

10.8 已分享檔案 906

10.9 I/O重定向 909

10.10 標準I/O 911

10.11 綜合:我該使用哪些I/O函式? 911

10.12 小結 913

參考文獻說明 914

家庭作業 914

練習題答案 915

第11章 網路編程 917

11.1 客戶端–伺服器編程模型 918

11.2 網路 919

11.3 全球IP網際網路 924

11.3.1 IP位址 925

11.3.2 網際網路域名 927

11.3.3 網際網路連線 929

11.4 套接字接口 932

11.4.1 套接字地址結構 933

11.4.2 socket函式 934

11.4.3 connect函式 934

11.4.4 bind函式 935

11.4.5 listen函式 935

11.4.6 accept函式 936

11.4.7 主機和服務的轉換 937

11.4.8 套接字接口的輔助函式 942

11.4.9 echo客戶端和伺服器的示例 944

11.5 Web伺服器 948

11.5.1 Web基礎 948

11.5.2 Web內容 949

11.5.3 HTTP事務 950

11.5.4 服務動態內容 953

11.6 綜合:TINY Web伺服器 956

11.7 小結 964

參考文獻說明 965

家庭作業 965

練習題答案 966

第12章 並發編程 971

12.1 基於進程的並發編程 973

12.1.1 基於進程的並發伺服器 974

12.1.2 進程的優劣 975

12.2 基於I/O多路復用的並發編程 977

12.2.1 基於I/O多路復用的並發事件驅動伺服器 980

12.2.2 I/O多路復用技術的優劣 985

12.3 基於執行緒的並發編程 985

12.3.1 執行緒執行模型 986

12.3.2 Posix執行緒 987

12.3.3 創建執行緒 988

12.3.4 終止執行緒 988

12.3.5 回收已終止執行緒的資源 989

12.3.6 分離執行緒 989

12.3.7 初始化執行緒 990

12.3.8 基於執行緒的並發伺服器 991

12.4 多執行緒程式中的共享變數 992

12.4.1 執行緒記憶體模型 993

12.4.2 將變數映射到記憶體 994

12.4.3 共享變數 995

12.5 用信號量同步執行緒 995

12.5.1 進度圖 999

12.5.2 信號量 1001

12.5.3 使用信號量來實現互斥 1002

12.5.4 利用信號量來調度共享資源 1004

12.5.5 綜合:基於預執行緒化的並發伺服器 1008

12.6 使用執行緒提高並行性 1013

12.7 其他並發問題 1020

12.7.1 執行緒安全 1020

12.7.2 可重入性 1023

12.7.3 線上程化的程式中使用已存在的庫函式 1024

12.7.4 競爭 1025

12.7.5 死鎖 1027

12.8 小結 1030

參考文獻說明 1030

家庭作業 1031

練習題答案 1036

附錄A 錯誤處理 1041

參考文獻 1047

相關詞條

熱門詞條

聯絡我們