Skip to main content

Command Palette

Search for a command to run...

Tổ chức bộ nhớ của hệ điều hành

Updated
4 min read

Bộ nhớ của máy tính bao gồm các loại sau:

  1. Thanh ghi (nằm trong CPU) - Register

    Thanh ghi là bộ nhớ có dung lượng rất nhỏ nằm trực tiếp trong CPU và được quản lý trực tiếp bởi CPU.

    Đây là nơi lưu giữ:

    Toán hạng đang được xử lý.

    Kết quả trung gian.

    Địa chỉ bộ nhớ, trạng thái CPU, lệnh đang được thực thi.

    Thanh ghi có tốc độ truy xuất nhanh nhất trong bộ nhớ của CPU.

  2. Bộ nhớ đệm (nằm giữa CPU và RAM) - Cache

    Đây là bộ nhớ tạm thời tốc độ cao dùng để lưu dữ liệu và lệnh truy cập thường xuyên.

    Bộ nhớ Cache nằm giữa CPU và Bộ nhớ chính (RAM).

    Khi CPU cần dữ liệu, sẽ truy cập Cache trước, nếu có (Cache hit) sẽ dùng ngay, nếu không có (Cache miss) sẽ truy cập RAM để lấy dữ liệu, sau đó dữ liệu đó được copy vào Cache để dùng cho lần sau.

    Kích thước của Cache thông thường từ vài KB đến 4 MB tùy thuộc loại Cache L1, L2 hay L3.

  3. Bộ nhớ chính - RAM

    Đây là bộ nhớ lưu giữ chương trình và dữ liệu đang được thực thi.

    RAM nằm ngoài CPU và được kết nối với CPU thông qua bus bộ nhớ và có tốc độ chậm hơn Cache.

    Khi chương trình chạy, hệ điều hành nạp chương trình và dữ liệu từ Disk vào RAM, CPU không truy cập trực tiếp vào Disk mà làm việc trực tiếp với dữ liệu ở trong RAM.

    Dữ liệu trong RAM có thể được copy vào Register hoặc Cache để tăng tốc độ truy xuất dữ liệu.

    Dữ liệu trong RAM sẽ mất khi mất điện.

  4. Disk - SSD

    Ổ cứng SSD là nơi lưu dữ liệu lâu dài. Dữ liệu không mất khi mất điện.

    CPU không truy cập dữ liệu trực tiếp trong Disk mà sẽ được Load vào RAM để xử lý.

Sau đây chúng ta sẽ viết một chương trình c để xem tốc độ truy xuất dữ liệu của các loại bộ nhớ trên hệ điều hành Linux.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>

#define LOOP            100000000

#define SMALL_SIZE      (32 * 1024)             // 32 KB (L1 Cache size)
#define LARGE_SIZE      (200 * 1024 * 1024)     // 200 MB (vượt qua kích thước của Cache)

#define CACHE_LINE      64                      // kích thước Cache Line là 64 byte

// Hàm lấy số giây đã trôi qua kể từ khi hệ thống khởi động
double now() {
    struct timespec t;
    clock_gettime(CLOCK_BOOTTIME, &t);
    return t.tv_sec + t.tv_nsec*1e-9;
}

int main() {
    double t;

    // 1. Mô phỏng thời gian CPU truy cập Cache
    // Mảng small được cấp phất một mảng đúng bằng 32KB vừa với kích thước của L1 Cache
    // do đó tỷ lệ Cache miss rất ít
    char* small = malloc(SMALL_SIZE);
    memset(small, 0, SMALL_SIZE);

    t = now();
    for (size_t i = 0; i < LOOP; i++)
    {
        // i * CACHE_LINE đảm bảo mỗi lần load dữ liệu ở một cache line mới
        small[(i * CACHE_LINE) % SMALL_SIZE]++;
    }
    printf("Thời gian truy cập Cache: %.3f ms\n", now() - t);

    // 2. Mô phỏng thời gian CPU truy cập RAM
    // Mảng large được cấp phát là 200 MB lớn hơn rất nhiều so với kích thước của L3 Cache
    // do đó sẽ xuất hiện Cache miss tương đối lớn
    char* larger = malloc(LARGE_SIZE);
    memset(larger, 0, LARGE_SIZE);

    t = now();
    for (size_t i = 0; i < LOOP; i ++)
    {
        larger[(i * CACHE_LINE) % LARGE_SIZE]++;
    }
    printf("Thời gian truy cập RAM: %.3f ms\n", now() - t);

    // 3. Mô phỏng thời gian hệ điều hành truy cập ổ cứng
    // Ghi mảng large ra file đồng bộ
    int fd = open("demo.bin", O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0644);
    t = now();
    write(fd, larger, LARGE_SIZE);
    close(fd);
    printf("Thời gian ghi 200MB ra Disk: %.3f ms\n", now() - t);

    // Giải phóng bộ nhớ
    free(small);
    free(larger);

    return 0;
}

Kết quả:

Kết luận:

  1. Mảng 32 KB có kích thước vừa với L1 Cache, tỷ lệ Cache miss thấp, thời gian truy cập rất nhanh

  2. Mảng 200 MB vượt Cache size, nhiều Cache miss, CPU phải truy cập từ RAM, thời gian truy cập lâu hơn Cache

  3. Ghi ra SSD là tầng thực sự chậm hơn RAM nhưng trên Linux SSD cũng có cache cho SSD trên RAM, hàm write() thực tế trả về ngay khi dữ liệu được ghi vào SSD cache nên thời gian 0.422 ms thực tế chưa phản ánh thời gian ghi file ra SSD.

The End.

More from this blog

U40 Học Code - Lập trình & Hệ điều hành

11 posts