CPU được thiết kế và xây dựng như thế nào
- OFREZH EDITOR
- 21 thg 6
- 13 phút đọc
Chúng ta đều nghĩ CPU là "bộ não" của máy tính, nhưng điều đó thực sự có nghĩa là gì? Điều gì đang diễn ra bên trong hàng tỷ bóng bán dẫn giúp máy tính của bạn hoạt động? Trong loạt bài gồm bốn phần này, chúng ta sẽ tập trung vào thiết kế phần cứng máy tính, đề cập đến những điều cơ bản tạo nên chức năng của máy tính.
Chuỗi bài này sẽ đề cập đến kiến trúc máy tính, thiết kế mạch xử lý, VLSI (tích hợp quy mô rất lớn), chế tạo chip và xu hướng tương lai trong lĩnh vực điện toán. Nếu bạn luôn quan tâm đến các chi tiết về cách bộ xử lý hoạt động bên trong, hãy theo dõi – đây là những thông tin bạn cần biết để bắt đầu.
Phần 1: Kiến trúc máy tính cơ bản
(bộ hướng dẫn, bộ nhớ đệm, đường ống, siêu phân luồng)
Phần 2: Quy trình thiết kế CPU
(sơ đồ, bóng bán dẫn, cổng logic, xung nhịp)
Phần 3: Bố trí và xây dựng Chip vật lý
(pha tạp, nút xử lý, chế tạo silicon)
Phần 4: Xu hướng Chủ đề nóng trong tương lai về Kiến trúc máy tính
(biển máy gia tốc, tích hợp 3D, ASIC, điện toán gần bộ nhớ)

CPU thực sự có chức năng gì?
Hãy bắt đầu ở cấp độ rất cao với những gì bộ xử lý làm và cách các khối xây dựng kết hợp với nhau trong một thiết kế hoạt động. Điều này bao gồm lõi bộ xử lý, hệ thống phân cấp bộ nhớ, dự đoán nhánh và nhiều hơn nữa. Trước tiên, chúng ta cần một định nghĩa cơ bản về những gì CPU làm.
Giải thích đơn giản nhất là CPU tuân theo một tập hợp các lệnh để thực hiện một số thao tác trên một tập hợp các đầu vào. Ví dụ, điều này có thể là đọc một giá trị từ bộ nhớ, thêm nó vào một giá trị khác và cuối cùng lưu trữ kết quả trở lại bộ nhớ ở một vị trí khác. Nó cũng có thể là một cái gì đó phức tạp hơn, như chia hai số nếu kết quả của phép tính trước đó lớn hơn không.
Khi bạn muốn chạy một chương trình như hệ điều hành hoặc trò chơi, bản thân chương trình là một chuỗi các lệnh để CPU thực thi. Các lệnh này được tải từ bộ nhớ và trên một bộ xử lý đơn giản, chúng được thực thi từng lệnh một cho đến khi chương trình hoàn tất. Trong khi các nhà phát triển phần mềm viết chương trình của họ bằng các ngôn ngữ cấp cao như C++ hoặc Python, chẳng hạn, bộ xử lý không thể hiểu được điều đó. Nó chỉ hiểu 1 và 0, vì vậy chúng ta cần một cách để biểu diễn mã theo định dạng này.

Những điều cơ bản về lệnh CPU
Các chương trình được biên dịch thành một tập hợp các lệnh cấp thấp được gọi là ngôn ngữ lắp ráp như một phần của Kiến trúc tập lệnh (ISA). Đây là tập hợp các lệnh mà CPU được xây dựng để hiểu và thực thi. Một số ISA phổ biến nhất là x86, MIPS, ARM, RISC-V và PowerPC. Giống như cú pháp để viết một hàm trong C++ khác với một hàm thực hiện cùng một việc trong Python, mỗi ISA có cú pháp riêng.
Các ISA này có thể được chia thành hai loại chính: độ dài cố định và độ dài thay đổi. RISC-V ISA sử dụng các lệnh có độ dài cố định, nghĩa là một số bit được xác định trước trong mỗi lệnh sẽ xác định loại lệnh đó là gì. Điều này khác với x86, sử dụng các lệnh có độ dài thay đổi. Trong x86, các lệnh có thể được mã hóa theo nhiều cách khác nhau và với số lượng bit khác nhau cho các phần khác nhau. Do tính phức tạp này, bộ giải mã lệnh trong CPU x86 thường là phần phức tạp nhất trong toàn bộ thiết kế.
Các lệnh có độ dài cố định cho phép giải mã dễ dàng hơn do cấu trúc thông thường của chúng nhưng giới hạn tổng số lệnh mà ISA có thể hỗ trợ. Trong khi các phiên bản phổ biến của kiến trúc RISC-V có khoảng 100 lệnh và là mã nguồn mở, x86 là độc quyền và không ai thực sự biết có bao nhiêu lệnh tồn tại. Mọi người thường tin rằng có một vài nghìn lệnh x86, nhưng con số chính xác không được công khai. Mặc dù có sự khác biệt giữa các ISA, nhưng tất cả chúng đều mang về cơ bản cùng một chức năng cốt lõi.

Ví dụ về một số lệnh RISC-V. Mã lệnh bên phải là 7 bit và xác định loại lệnh. Mỗi lệnh cũng chứa các bit cho các thanh ghi nào để sử dụng và các chức năng nào để thực hiện. Đây là cách các lệnh lắp ráp được chia nhỏ thành nhị phân để CPU có thể hiểu.
Bây giờ chúng ta đã sẵn sàng bật máy tính và bắt đầu chạy mọi thứ. Thực hiện một lệnh thực sự có một số phần cơ bản được chia nhỏ qua nhiều giai đoạn của bộ xử lý.
Lấy, Giải mã, Thực thi: Chu kỳ thực thi của CPU
Bước đầu tiên là lấy lệnh từ bộ nhớ vào CPU để bắt đầu thực thi. Ở bước thứ hai, lệnh được giải mã để CPU có thể xác định đó là loại lệnh nào. Có nhiều loại, bao gồm lệnh số học, lệnh nhánh và lệnh bộ nhớ. Khi CPU biết loại lệnh nào đang thực thi, các toán hạng cho lệnh sẽ được thu thập từ bộ nhớ hoặc các thanh ghi bên trong CPU. Nếu bạn muốn cộng số A với số B, bạn không thể thực hiện phép cộng cho đến khi bạn thực sự biết giá trị của A và B. Hầu hết các bộ xử lý hiện đại đều là 64 bit, nghĩa là kích thước của mỗi giá trị dữ liệu là 64 bit.

64-bit đề cập đến chiều rộng của một thanh ghi CPU, đường dẫn dữ liệu và/hoặc địa chỉ bộ nhớ. Đối với người dùng hàng ngày, điều đó có nghĩa là lượng thông tin mà máy tính có thể xử lý cùng một lúc và tốt nhất là so sánh với người anh em kiến trúc nhỏ hơn của nó, 32-bit. Kiến trúc 64-bit có thể xử lý gấp đôi lượng thông tin cùng một lúc (64 bit so với 32).
Sau khi CPU có toán hạng cho lệnh, nó chuyển sang giai đoạn thực hiện, tại đó hoạt động được thực hiện trên đầu vào. Có thể là thêm các số, thực hiện thao tác logic trên các số hoặc chỉ truyền các số qua mà không sửa đổi chúng. Sau khi kết quả được tính toán, bộ nhớ có thể cần được truy cập để lưu trữ kết quả hoặc CPU có thể chỉ giữ giá trị trong một trong các thanh ghi bên trong của nó. Sau khi kết quả được lưu trữ, CPU sẽ cập nhật trạng thái của các phần tử khác nhau và chuyển sang lệnh tiếp theo.
Tất nhiên, mô tả này là một sự đơn giản hóa rất lớn, và hầu hết các bộ xử lý hiện đại sẽ chia nhỏ một vài giai đoạn này thành 20 hoặc nhiều giai đoạn nhỏ hơn để cải thiện hiệu quả. Điều đó có nghĩa là mặc dù bộ xử lý sẽ bắt đầu và hoàn thành một số lệnh trong mỗi chu kỳ, nhưng có thể mất 20 hoặc nhiều chu kỳ hơn để bất kỳ lệnh nào hoàn thành từ đầu đến cuối. Mô hình này thường được gọi là đường ống vì mất một thời gian để lấp đầy đường ống và để chất lỏng đi qua hoàn toàn, nhưng khi đầy, bạn sẽ nhận được đầu ra không đổi.

Ví dụ về đường ống 4 giai đoạn. Các hộp màu đại diện cho các hướng dẫn độc lập với nhau.
Tín dụng hình ảnh: Wikipedia
Thực thi không theo thứ tự và kiến trúc siêu vô hướng
Toàn bộ chu kỳ mà một lệnh trải qua là một quá trình được biên đạo rất chặt chẽ, nhưng không phải tất cả các lệnh đều có thể hoàn thành cùng một lúc. Ví dụ, phép cộng rất nhanh, trong khi phép chia hoặc tải từ bộ nhớ có thể mất hàng trăm chu kỳ. Thay vì làm toàn bộ bộ xử lý dừng lại trong khi một lệnh chậm hoàn thành, hầu hết các bộ xử lý hiện đại thực hiện không theo thứ tự.
Điều đó có nghĩa là chúng sẽ xác định lệnh nào sẽ có lợi nhất để thực thi tại một thời điểm nhất định và đệm các lệnh khác chưa sẵn sàng. Nếu lệnh hiện tại chưa sẵn sàng, bộ xử lý có thể nhảy về phía trước trong mã để xem có lệnh nào khác đã sẵn sàng không.
Ngoài việc thực thi ngoài thứ tự, bộ xử lý hiện đại điển hình sử dụng cái gọi là kiến trúc siêu vô hướng . Điều này có nghĩa là tại bất kỳ thời điểm nào, bộ xử lý thực thi nhiều lệnh cùng lúc ở mỗi giai đoạn của đường ống. Nó cũng có thể chờ hàng trăm lệnh khác để bắt đầu thực thi. Để thực thi nhiều lệnh cùng lúc, bộ xử lý sẽ có nhiều bản sao của mỗi giai đoạn đường ống bên trong.
Nếu bộ xử lý thấy rằng hai lệnh đã sẵn sàng để thực thi và không có sự phụ thuộc giữa chúng, thay vì chờ chúng hoàn thành riêng rẽ, nó sẽ thực thi cả hai lệnh cùng lúc. Một triển khai phổ biến của điều này được gọi là Đa luồng đồng thời (SMT), còn được gọi là Siêu phân luồng. Bộ xử lý Intel và AMD thường hỗ trợ SMT hai chiều, trong khi IBM đã phát triển các chip hỗ trợ SMT tám chiều.

Để thực hiện được quá trình thực hiện được biên đạo cẩn thận này, một bộ xử lý có nhiều thành phần bổ sung ngoài lõi cơ bản. Có hàng trăm mô-đun riêng lẻ trong một bộ xử lý, mỗi mô-đun phục vụ một mục đích cụ thể, nhưng chúng ta sẽ chỉ xem xét những điều cơ bản. Hai thành phần lớn nhất và có lợi nhất là bộ đệm và bộ dự đoán nhánh. Các cấu trúc bổ sung mà chúng ta sẽ không đề cập bao gồm những thứ như bộ đệm sắp xếp lại, bảng bí danh đăng ký và trạm đặt chỗ.
Bộ nhớ đệm: Tăng tốc truy cập bộ nhớ
Mục đích của bộ nhớ đệm thường gây nhầm lẫn vì chúng lưu trữ dữ liệu giống như RAM hoặc SSD . Tuy nhiên, điều khiến bộ nhớ đệm trở nên khác biệt là độ trễ truy cập và tốc độ của chúng. Mặc dù RAM cực kỳ nhanh, nhưng nó chậm hơn CPU gấp nhiều lần. RAM có thể mất hàng trăm chu kỳ để phản hồi dữ liệu và bộ xử lý sẽ không có việc gì để làm. Nếu dữ liệu không nằm trong RAM, có thể mất hàng chục nghìn chu kỳ để dữ liệu trên SSD được truy cập. Nếu không có bộ nhớ đệm, bộ xử lý của chúng ta sẽ phải dừng lại.
Bộ xử lý thường có ba cấp bộ nhớ đệm tạo thành thứ được gọi là hệ thống phân cấp bộ nhớ . Bộ nhớ đệm L1 là nhỏ nhất và nhanh nhất, L2 ở giữa và L3 là lớn nhất và chậm nhất trong các bộ nhớ đệm. Phía trên các bộ nhớ đệm trong hệ thống phân cấp là các thanh ghi nhỏ lưu trữ một giá trị dữ liệu duy nhất trong quá trình tính toán. Các thanh ghi này là thiết bị lưu trữ nhanh nhất trong hệ thống của bạn theo cấp số nhân. Khi trình biên dịch chuyển đổi một chương trình cấp cao thành ngôn ngữ lắp ráp, nó sẽ xác định cách tốt nhất để sử dụng các thanh ghi này.
Khi CPU yêu cầu dữ liệu từ bộ nhớ, trước tiên nó sẽ kiểm tra xem dữ liệu đó đã được lưu trữ trong bộ đệm L1 chưa. Nếu đã lưu trữ, dữ liệu có thể được truy cập nhanh chóng chỉ trong vài chu kỳ. Nếu không có, CPU sẽ kiểm tra bộ đệm L2 và sau đó tìm kiếm bộ đệm L3. Bộ đệm được triển khai theo cách mà chúng thường trong suốt đối với lõi. Lõi sẽ chỉ yêu cầu một số dữ liệu tại một địa chỉ bộ nhớ đã chỉ định và bất kỳ cấp độ nào trong hệ thống phân cấp có dữ liệu đó sẽ phản hồi. Khi chúng ta chuyển sang các giai đoạn tiếp theo trong hệ thống phân cấp bộ nhớ, kích thước và độ trễ thường tăng theo cấp số nhân. Cuối cùng, nếu CPU không thể tìm thấy dữ liệu mà nó đang tìm kiếm trong bất kỳ bộ đệm nào, thì khi đó nó mới chuyển đến bộ nhớ chính (RAM).

Comments