跳转至

3.2 Computer Hardware

Wed Lecture

主要讲述计算机结构体系中的知识,直到 Week 4 Mon 全部讲完

Main Structural Components

  1. 中央处理器 (CPU - Central Processing Unit)
  2. 执行算术和逻辑计算 (Arithmetic and Logical Computation)。
  3. 管理大部分内存和外围设备的输入输出 (Input and Output Services)。
  4. 可能有多个处理器 (Multiple Processors) 共同执行操作系统或应用程序 (Operating System or User/Application Programs)。

  5. 主存储器 (RAM - Random Access Memory)

  6. 存储指令和数据 (Instructions and Data)。
  7. 处理器在程序的指导下读取和写入内存中的数据 (Read and Write Memory as Directed by Programs)。

  8. 辅助存储器和外围设备 (Secondary Storage and Peripheral Devices)

  9. 提供长期、持久的数据存储 (Long-term Persistent Storage),如磁盘 (Disks)、磁带 (Tapes)。
  10. 包含输入/输出模块和I/O控制器 (I/O Controllers)。

  11. 系统总线 (System Bus)

  12. 连接处理器、主内存和I/O设备 (Connects Processor, Main Memory, and I/O Devices)。
  13. 充当数据传输的“高速公路” (Data "Highway")。
  14. 只有一个组件可以控制总线 (Only One Component Can Control the Bus),通常通过总线仲裁决定 (Bus Arbitration)。

Processor Registers

  • 寄存器 是处理器内部的非常快速的存储位置 (Fast Memory Locations Inside the Processor)。
  • 访问时间通常为 0.5-3 纳秒 (Access Time: 0.5-3 ns)。
  • 如果数据在寄存器中而不是在主内存中,程序执行速度可能提高 10-500 倍 (Execution Speed Improvement: 10-500X)。
  • 处理器寄存器的数量和宽度(如 64 位寄存器)影响 CPU 的性能和速度 (Number and Width of Registers Affect CPU Performance)。

  • 寄存器类型 (Register Types):

  • 用户可访问寄存器 (User-Accessible Registers)

    • 数据寄存器 (Data Registers):存储数据值和运算结果 (Hold Values Before and After Instructions)。
    • 地址寄存器 (Address Registers):存储内存位置的地址 (Hold Addresses of Memory Locations)(如 MAR、MBR、索引寄存器、栈指针)。
  • 控制和状态寄存器 (Control and Status Registers)

    • 存储处理器状态 (Processor Status)(如指令寄存器 IR、程序计数器 PC)。
    • 处理器状态字 (PSW - Processor Status Word) 记录处理器状态和操作结果 (Records Processor Status and Operation Results)(如溢出、进位、除零错误)。

Memory Hierarchy

  • 内存层次结构 通过不同层次的内存来平衡成本、容量和访问时间 (Balancing Cost, Capacity, and Access Time):
  • 寄存器:最快,存储1-4KB数据 (Fastest, 1-4KB Data)。
  • L1/L2/L3 缓存:比主内存更快,容量从8KB到64MB不等 (Caches: 8KB-64MB)。
  • 主内存 (RAM):较大容量,访问时间10-60纳秒 (Larger Capacity, 10-60 ns Access Time)。
  • 硬盘:最慢,容量最大,访问时间为3M-10M纳秒 (Hard Disk: Slowest, Largest Capacity, 3M-10M ns Access Time)。
  • 固态硬盘 (SSD - Solid-State Disk):介于主内存和硬盘之间,访问时间为0.5M-1M纳秒 (Intermediate Between RAM and Hard Disk, 0.5M-1M ns Access Time)。

Data Rates and Byte Interpretation

  • 基本数据单元 (Basic Data Units):
  • 比特 (Bit):最小的数据单元 (Smallest Data Unit)。
  • 字节 (Byte):通常为8位,比特的基本组合单元 (Typically 8 Bits)。
  • (Word):处理器的默认数据大小 (Default Data Size for Processor);常见为32位或64位 (Common Word Sizes: 32 or 64 Bits)。

  • 数据解释 (Data Interpretation):

  • 数据的含义取决于上下文 (Meaning Depends on Context),例如:
    • 一串32位的位模式可能表示ASCII字符、32位整数、浮点值或内存地址 (32-bit Pattern Could Represent ASCII Characters, 32-bit Integer, Floating Point Value, or Memory Address)。
    • 错误的解释会导致处理器错误 (Errors in Interpretation Can Cause Processor Faults)。

Workshop

这个作业重点是用 C11 开发函数来计算地球表面上两点之间的距离,使用的是haversine 公式。

  1. 创建数据结构

  2. 定义一个 C11 结构体,用来表示地球上的一个地理点(即纬度和经度)。这将为你提供一个存储这些数据的方式。

  3. 开发三个函数

  4. degrees_to_radians(double degrees)——一个将角度转换为弧度的函数(因为这个公式是基于弧度计算的)。

  5. valid_location(struct point location)——一个函数,用来检查一个给定的位置是否合法(例如,纬度必须在 -90° 到 90° 之间)。

  6. haversine(struct point location1, struct point location2)——主要函数,用来计算两点之间的距离。

  7. 设计命令行工具

  8. 实现程序,接受从命令行传入的坐标对,返回计算出的距离(以米为单位)。

  9. 测试并扩展

  10. 首先,计算两点之间的距离。

  11. 然后,开发另一个工具,用于处理多个点,计算从第一个点到最后一个点的距离,路径沿途经过所有点。

VIM Template

教授直接执行 \vc 就开了一个能够快速编写 C 代码的模版,这种编写模版可以自己在某处创建一个 blank.c 做到

Solutions

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>

// 定义地球半径,单位为米
#define EARTH_RADIUS 6371000

// 定义结构体,表示地球上的一个点(即一个地理位置:纬度和经度)
struct point {
    double latitude;
    double longitude;
};

// 将角度转换为弧度的函数
double degrees_to_radians(double degrees) {
    return degrees * M_PI / 180.0;
}

// 检查一个点是否合法的函数(纬度必须在-90到90之间, 经度必须在-180到180之间)
bool valid_location(struct point location) {
    return location.latitude >= -90 && location.latitude <= 90 &&
           location.longitude >= -180 && location.longitude <= 180;
}

// 使用 haversine 公式计算两点之间的距离
double haversine(struct point location1, struct point location2) {
    double lat1 = degrees_to_radians(location1.latitude);
    double lon1 = degrees_to_radians(location1.longitude);
    double lat2 = degrees_to_radians(location2.latitude);
    double lon2 = degrees_to_radians(location2.longitude);

    double dlat = lat2 - lat1;
    double dlon = lon2 - lon1;

    // haversine 公式
    double a = sin(dlat / 2) * sin(dlat / 2) +
               cos(lat1) * cos(lat2) *
               sin(dlon / 2) * sin(dlon / 2);
    double c = 2 * atan2(sqrt(a), sqrt(1 - a));

    return EARTH_RADIUS * c;
}

// 命令行工具:计算两点之间的距离
int main(int argc, char *argv[]) {
    if (argc != 5) {
        printf("Usage: %s lat1 lon1 lat2 lon2\n", argv[0]);
        return 1;
    }

    struct point location1, location2;

    // 从命令行参数读取位置
    location1.latitude = atof(argv[1]);
    location1.longitude = atof(argv[2]);
    location2.latitude = atof(argv[3]);
    location2.longitude = atof(argv[4]);

    // 验证输入的位置是否合法
    if (!valid_location(location1) || !valid_location(location2)) {
        printf("Invalid location coordinates.\n");
        return 1;
    }

    // 计算两点之间的距离
    double distance = haversine(location1, location2);
    printf("Distance: %.0f metres\n", distance);

    return 0;
}