CPU (Central Processing Unit) – cũng được gọi là microprocessor hay processor – là một đơn vị xử lý dữ liệu trung tâm. Tuy mỗi một bộ vi xử lý đều có thiết kế của riêng nhưng tất cả đều có cùng một nguyên lý chung – đây chính là thứ mà chúng tôi muốn giới thiệu đến các bạn trong bài này. Chúng tôi sẽ giới thiệu đến kiến trúc CPU chung nhất để các bạn có thể hiểu thêm về các sản phẩm của Intel và AMD cũng như những khác nhau cơ bản giữa chúng. Bài trước chúng ta đã được biết những thông tin cơ bản về Clock và External Clock hoạt động trong CPU, bài này sẽ tiếp tục với sơ đồ của một CPU và bộ nhớ lưu trữ.
Sơ đồ khối của một CPU
Trên hình 6 bạn có thể thấy được một sơ đồ khối cơ bản của một CPU hiện đại. Có nhiều sự khác nhau giữa các kiến trúc của AMD và Intel. Việc hiểu được các kiến thức cơ bản này sẽ là một bước để các bạn có thể hiểu được cách các CPU của Intel và AMD làm việc như thế nào và sự khác nhau giữa chúng.
Hình 6: Sơ đồ khối cơ bản của một CPU
Dòng nét chấm trên hình 6 thể hiện phần “body” của CPU, vì bộ nhớ RAM được đặt bên ngoài CPU. Đường dữ liệu (datapath) giữa bộ nhớ RAM và CPU thường là 64-bit (hoặc 128-bit khi sử dụng cấu hình bộ nhớ kênh dual), đang sử dụng clock nhớ hoặc clock ngoài của CPU (clock thấp). Số lượng bit đã sử dụng và tốc độ clock có thể được kết hợp trong một khối có tên gọi là tốc độ truyền tải, tính theo MB/s. Để tính toán tốc độ truyền tải, công thức được thực hiện tính tốc độ này bằng số bit x clock/8. Với hệ thống sử dụng các bộ nhớ DDR400 trong cấu hình kênh đơn (64 bit) thì tốc độ truyền tải sẽ là 3.200MB/s, còn với hệ thống tương tự sử dụng các bộ nhớ kênh dual (128 bit) sẽ có tốc độ truyền tải bộ nhớ là 6.400 MB/s.
Tất cả các mạch bên trong phần đánh dấu chấm chạy ở tốc độ clock trong của CPU. Tùy thuộc vào CPU mà một số phần bên trong nó có thể chạy ở tốc độ clock cao hơn. Cũng vậy, đường dữ liệu giữa các khối CPU có thể rộng hơn, nghĩa là truyền tải nhiều bit hơn trên mỗi chu kỳ clock 64 hoặc 128. Ví dụ, đường dữ liệu giữa bộ nhớ cache L2 và cache chỉ lệnh L1 trên các bộ vi xử lý hiện đại thường là 256 bit. Số bit được truyền tải trên mỗi chu kỳ clock càng cao thì sự truyền tải sẽ được thực hiện càng nhanh (hay nói cách khác, tốc độ truyền tải sẽ cao hơn). Trên hình 5, chúng tôi đã sử dụng một mũi tên đỏ giữa bộ nhớ RAM và cache nhớ L2; mũi tên giữa các khối khác để diễn tả tốc độ clock khác nhau và bề rộng của đường dữ liệu đã sử dụng.
Memory Cache
Memory Cache là một kiểu bộ nhớ hiệu suất cao, cũng được gọi là bộ nhớ tĩnh. Kiểu bộ nhớ đã sử dụng trên bộ nhớ RAM chính của máy tính được gọi là bộ nhớ động. Bộ nhớ tĩnh tiêu tốn nhiều năng lượng điện hơn, đắt hơn và có kích thước vật lý lớn hơn so với bộ nhớ động, tuy nhiên nó lại chạy nhanh hơn. Nó có thể làm việc với cùng tốc độ clock của CPU, điều mà bộ nhớ động không thể thực hiện được.
Vào “thế giới bên ngoài” để tìm nạp dữ liệu làm cho CPU phải làm việc ở tốc độ clock thấp hơn do vậy mà kỹ thuật cache nhớ được sử dụng ở đây để khắc phục nhược điểm này. Khi CPU nạp dữ liệu từ một vị trí nhớ nào đó thì mạch có tên gọi là memory cache controller (mạch này không được vẽ trong hình 6) nạp vào cache nhớ một khối dữ liệu bên dưới vị trí hiện hành mà CPU đã nạp. Vì các chương trình được thực hiện theo thứ tự nên vị trí nhớ tiếp theo mà CPU sẽ yêu cầu có thể là vị trí ngay dưới vị trí nhớ mà nó đã nạp. Do memory cache controller đã nạp rất nhiều dữ liệu dưới vị trí nhớ đầu tiên được đọc bởi CPU nên dữ liệu kế tiếp sẽ ở bên trong cache nhớ, chính vì vậy CPU không cần phải thực hiện thao tác lấy dữ liệu bên ngoài: nó đã được nạp vào bên trong cache nhớ nhúng trong CPU, chính vì nhúng trong CPU mà chúng có thể truy cập bằng tốc độ clock trong.
Cache controller luôn luôn quan sát các vị trí nhớ đã và đang được nạp dữ liệu từ một vài vị trí nhớ sau khi vị trí nhớ vừa được đọc. Một ví dụ thực tế, nếu một CPU đã nạp dữ liệu được lưu tại địa chỉ 1.000 thì cache controller sẽ nạp dữ liệu từ “n” địa chỉ sau địa chỉ 1.000. Số “n” được gọi là trang; nếu một bộ vi xử lý này làm việc với trang 4KB (giá trị điển hình) thì nó sẽ nạp dữ liệu từ các địa chỉ 4.096 dưới vị trí nhớ hiện hành đang được nạp (địa chỉ 1.000 trong ví dụ). 1KB bằng 1.024 byte, do đó là 4,096 chứ không phải 4,000. Chúng tôi đã thể hiện ví dụ này trên hình 7.
Hình 7: Memory cache controller làm việc như thế nào
Memory cache càng lớn thì cơ hội cho dữ liệu yêu cầu bởi CPU ở đây càng cao, chính vì vậy CPU sẽ giảm sự truy cập trực tiếp vào bộ nhớ RAM, do đó hiệu suất hệ thống tăng (khi CPU cần truy cập trực tiếp vào bộ nhớ RAM thì nó phải thực hiện ở tốc độ clock thấp hơn nên giảm hiệu suất của toàn hệ thống).
Chúng ta gọi là “hit” khi CPU nạp một dữ liệu yêu cầu từ cache và “miss” nếu dữ liệu yêu cầu không có ở đó và CPU cần phải truy cập vào bộ nhớ RAM của hệ thống.
L1 và L2 tương ứng là “Level 1” và “Level 2”, được đại diện cho khoảng cách từ chúng đến lõi CPU (khối thực thi). Một sự ngờ vực hay có ở đây là tại sao có đến 3 bộ nhớ Cache (L1 data cache, L1 instruction cache và L2 cache). Hãy chú ý trên hình 6 và bạn sẽ thấy được rằng L1 instruction cache làm việc như một “input cache”, trong khi đó L1 data cache làm việc như một “output cache”. L1 instruction cache – thường nhỏ hơn L2 cache – chỉ hiệu quả khi chương trình bắt đầu lặp lại một phần nhỏ của nó (loop), vì các chỉ lệnh yêu cầu sẽ gần hơn với khối tìm nạp.
Trên trang chi tiết kỹ thuật của một CPU, L1 cache có thể được thể hiện bằng một hình ảnh hoàn toàn khác. Một số nhà sản xuất liệt kê hai L1 cache riêng biệt (đôi khi gọi cache chỉ lệnh là “I” và cache dữ liệu là “D”), một số hãng ghi số lượng của cả hai là 128 KB nhưng điều đó có nghĩa là 64 KB cho cache chỉ lệnh và 64 KB cho cache dữ liệu. Mặc dù vậy đối với các CPU Pentium 4 và Celeronn đời sau dựa trên socket 478 và 775 thì không có hiện tượng này.
Các bộ vi xử lý Pentium 4 (và các bộ vi xử lý Celeron sử dụng socket 478 và 775) không có L1 instruction cache mà thay vào đó chúng có một trace execution cache, đây là cache được đặt giữa khối giải mã và khối thực thi. Chính vì vậy đây là L1 instruction cache nhưng tên đã được thay đổi và ở một vị trí cũng khác. Chúng ta đang đề cập đến điều này là vì đây là một lỗi rất thường xảy ra khi nghĩ rằng các bộ vi xử lý Pentium 4 không có L1 instruction cache. Vậy khi so sánh Pentium 4 với các CPU khác mọi người hãy nghĩ rằng L1 cache của nó nhỏ hơn nhiều.
Rẽ nhánh
Nhưng chúng tôi đã đề cập đến một vài lần từ trước, một trong những vấn đề chính đối với các CPU là có quá nhiều ‘”miss” đối với cache, vì khối tìm nạp phải truy cập trực tiếp vào bộ nhớ RAM (chậm), nên làm chậm cả hệ thống.
Thường sử dụng cache nhớ tránh được rất nhiều vấn đề này nhưng có một giải pháp điển hình có thể giải quyết vấn đề này đó là rẽ nhánh: Nếu ở giữa chương trình có một chỉ lệnh JMP (“jump” hoặc “go to”) gửi chương trình đến một vị trí nhớ khác hoàn toàn, vị trí mới này sẽ không được nạp trong L2 memory cache, mà chỉ làm cho khối tìm nạp vào vị trí đó một cách trực tiếp trong bộ nhớ RAM. Để giải quyết vấn đề này, cache controller của các CPU hiện đại phân tích khối nhớ mà nó đã nạp và bất cứ khi nào có tìm thấy một chỉ lệnh JMP thì nó sẽ nạp khối nhớ này vào vị trí đó trong L2 memory cache trước khi CPU xử lý chỉ lệnh JMP đó.
Hình 8: Giải pháp nhánh không điều kiện
Điều này quả mang lại sự thực thi dễ dàng hơn nhiều, vấn đề ở đây là khi chương trình có một rẽ nhánh điều kiện, nghĩa là địa chỉ mà chương trình sẽ vào phụ thuộc vào một điều kiện vẫn chưa được biết. Ví dụ, nếu a =< b vào địa chỉ 1, hoặc nếu a>b thì vào địa chỉ 2. Chúng tôi minh họa ví dụ này trên hình 9. Điều này sẽ tạo ra một “miss” đối với cache, vì các giá trị của a và b hoàn toàn không được biết đến và cache controller sẽ chỉ đang xem xét các chỉ lệnh giống JMP. Giải pháp thực hiện ở đây là: cache controller nạp cả hai điều kiện vào cache nhớ. Sau khi CPU xử lý chỉ lệnh rẽ nhánh, nó sẽ đơn giản loại bỏ một trường hợp không được chọn. Việc nạp bộ nhớ cache với dữ liệu không cần thiết sẽ tốt hơn so với việc truy cập vào bộ nhớ RAM.
Hình 9: Giải pháp rẽ nhánh có điều kiện