Bộ dự đoán nhánh 2-Ahead của Zen 5: một ý tưởng 30 năm tuổi mở ra khả năng mới
(chipsandcheese.com)- AMD Zen 5 giới thiệu bộ dự đoán nhánh 2-Ahead trong bối cảnh thiết kế lại toàn diện kiến trúc Zen, đưa trở lại mở rộng frontend x86 hiện đại một hướng nghiên cứu dự đoán nhánh đi trước nhiều khối từ thập niên 1990
- Dự đoán nhánh là cơ chế cho phép frontend CPU tiếp tục nạp lệnh ngay cả trước khi có kết quả của nhánh điều kiện; dự đoán sai sẽ dẫn tới chi phí flush pipeline và khởi động lại
- Zen 5 dùng 2 fetch pipe 32 byte/chu kỳ từ bộ nhớ đệm lệnh L1 32KB, mỗi pipe nối với một cụm giải mã 4-wide; Op Cache cũng có cấu trúc dual-ported 6-wide để cấp tối đa 12 operand cho Op Queue
- Cấu trúc mới xử lý 2 taken branch trong một chu kỳ trên các khối lệnh không liên tiếp, đồng thời dùng trường độ dài 5 bit để tìm điểm bắt đầu của cửa sổ dự đoán thứ ba nhằm giảm việc dùng quá mức tài nguyên decode và Op Cache
- Vì x86 có lệnh độ dài biến thiên nên rất khó song song hóa việc xác định ranh giới lệnh; do đó bộ dự đoán nhánh 2-Ahead cùng cấu trúc fetch·decode kép trở thành thay đổi cốt lõi trong việc mở rộng frontend dòng Zen
Những điểm thay đổi ở frontend của Zen 5
- AMD giới thiệu Zen 5 như một thiết kế lại toàn diện của kiến trúc Zen, và bộ dự đoán nhánh 2-Ahead là một trong những thay đổi nổi bật nhất
- Cấu trúc này quay trở lại từ các ý tưởng được bàn tới trong các bài báo cách đây 30 năm, trong xu hướng tiếp tục đẩy cao hiệu năng đơn nhân
- Khi dự đoán đồng thời nhiều taken branch, frontend có thể nhìn trước xa hơn vào luồng lệnh
Vì sao dự đoán nhánh cần thiết cho pipeline CPU
- CPU hiện đại dùng cấu trúc pipeline chia việc nạp lệnh (fetch), giải mã và thực thi thành nhiều giai đoạn
- Khi có nhánh điều kiện, frontend phải quyết định vị trí lệnh tiếp theo cần nạp trước khi việc đánh giá điều kiện hoàn tất
- Về cơ bản có hai lựa chọn
- Dừng lại cho tới khi có kết quả nhánh
- Dự đoán đường đi tiếp theo, và nếu sai thì loại bỏ phần công việc sai rồi khởi động lại từ điểm chắc chắn
- Nếu dự đoán sai, cần thực hiện flush để loại bỏ khỏi pipeline các công việc phụ thuộc vào phỏng đoán đó
- Chi phí dừng tại nhánh điều kiện tỷ lệ với số giai đoạn pipeline giữa instruction fetch và lúc hoàn tất đánh giá điều kiện nhánh
- Cuối cùng, CPU phải dự đoán luồng lệnh của chương trình chính xác nhất có thể
Bối cảnh ra đời của ý tưởng 2-Ahead
- Một cách dự đoán đơn giản là luôn coi backward jump ngắn là taken; về mặt lịch sử, chiến lược này hiệu quả hơn nhiều so với việc luôn nạp địa chỉ kế tiếp
- Nếu duy trì một lượng trạng thái nhỏ như lịch sử nhánh gần đây hay bản ghi địa chỉ, có thể đạt kết quả tốt hơn trên chương trình thực tế
- Chỉ với các cấu trúc cỡ vài chục KB, tỷ lệ dự đoán nhánh ở mức cuối 90% đã khả thi
- Bộ dự đoán nhánh 2-Ahead là đề xuất đã được thảo luận từ đầu thập niên 1990, khi bài toán mở rộng độ rộng kiến trúc lên 8-wide trở lên cũng được đặt ra
- Sau đó, khi CPU thương mại chuyển sang đa nhân, diện tích của từng lõi trở nên quan trọng hơn, còn giới học thuật tập trung vào cải tiến TAGE predictor hiệu quả hơn về diện tích
- Khi tiến trình thu nhỏ cho phép đặt nhiều transistor hơn trên cùng diện tích, mối quan tâm tới hiệu năng đơn nhân cũng tăng trở lại, song hành với xu hướng mở rộng tới hàng trăm CPU out-of-order
Vì sao frontend x86 khó hơn
- Các ISA dùng lệnh độ dài cố định như Arm 64-bit dễ giải mã song song những phần tùy ý của một dòng cache lệnh hơn
- Chỉ cần chia dữ liệu đầu vào theo các ranh giới byte lệnh đã được đảm bảo và nhân bản logic decoder
- x86 có độ dài lệnh biến thiên, nên muốn biết ranh giới tiếp theo của từng lệnh phải phân tích tuyến tính chuỗi byte lệnh
- Có thể song song hóa phần nào bằng cách pipeline kiểu giải mã sơ bộ prefix trước, nhưng chi phí trên x86 không hề thấp
- Đây cũng là lý do decode 4-wide từ lâu đã phổ biến trong các lõi x86 thiên về hiệu năng
- Những thiết kế như decode 6-wide của Intel Golden Cove chỉ trở nên khả thi thương mại nhờ mật độ logic cao hơn từ tiến trình mới, nhưng chi phí diện tích và điện năng của giải mã x86 song song nguyên khối tăng siêu tuyến tính theo độ rộng
- Mã số nguyên trong ứng dụng phổ thông thường có mật độ nhánh khoảng 1 branch mỗi 5~6 lệnh, làm giảm động lực mở rộng decoder rộng hơn nhiều
- Frontend x86 cần một cách bỏ qua bước khó song song hóa là xác định ranh giới lệnh, đồng thời vẫn đi tiếp an toàn tới ranh giới lệnh kế tiếp
Cách Zen 5 triển khai fetch·decode kép
- “Multiple-block ahead branch predictors” by Seznec et al. là bài báo cốt lõi nói về lý do và cách triển khai bộ dự đoán nhánh 2-Ahead
- Chỉ có predictor xử lý nhiều taken branch là chưa đủ; Seznec et al. cho rằng để tận dụng được nó mà không làm yêu cầu diện tích bùng nổ thì cần instruction fetch dual-porting
- Zen 5 chuyển instruction fetch và Op Cache sang cấu trúc dual-port
- Dùng 2 fetch pipe 32 byte/chu kỳ từ bộ nhớ đệm lệnh L1 32KB
- Mỗi fetch pipe nối với cụm decode 4-wide riêng
- Op Cache là thiết kế dual-ported 6-wide và có thể cấp tối đa 12 operand cho Op Queue
- Branch Target Buffer cũng nằm trong nhóm được dual-porting
- Quy mô lớn 16K entries mà L1 BTB của Zen 5 có thể truy cập có thể giải thích khả năng đây là L1 BTB dual-ported
- L2 BTB có 8K entries, nhỏ hơn L1 BTB
- AMD dùng L2 BTB giống như một victim cache, trong đó entry bị đẩy khỏi L1 BTB sẽ chuyển sang L2 BTB
Cách xử lý 2 taken branch trong một chu kỳ
- Zen 5 có thể xử lý 2 taken branch trong một chu kỳ trên các khối lệnh không liên tiếp
- Thay đổi này làm giảm mất băng thông fetch khi gặp taken branch và cho phép dự đoán xa hơn qua hai taken branch
- Vì có thể nhìn xa hơn vào luồng lệnh sau taken branch thứ hai, nó có thể có ba cửa sổ dự đoán
- Cả ba cửa sổ dự đoán đều có thể được dùng để tạo lệnh cho decode
- Cửa sổ dự đoán thứ hai có gắn trường độ dài 5 bit
- Giúp ngăn tình trạng đặt trước quá mức tài nguyên decode hoặc Op Cache
- Nhỏ hơn pointer nhưng vẫn cung cấp điểm bắt đầu cho cửa sổ dự đoán thứ ba
- Khi cửa sổ dự đoán thứ ba vượt qua ranh giới cache line, không cần lưu thêm trạng thái vào chỉ mục tra cứu dự đoán của chu kỳ kế tiếp
- Nếu cửa sổ dự đoán thứ ba nằm trong cùng cache line với cửa sổ dự đoán thứ nhất hoặc thứ hai, phần cửa sổ thứ ba không đầy đủ đó sẽ kém hiệu quả hơn một cửa sổ dự đoán thứ ba hoàn chỉnh
Những ràng buộc còn lại trong SMT
- Khi hai luồng cùng hoạt động trên Zen 5, fetch pipe gắn với decode cluster sẽ bị phân vùng tĩnh
- Trong trạng thái này, để hoạt động như một lõi dual fetch, hệ thống phải fetch từ cả L1 instruction cache lẫn Op Cache
- Lý do AMD làm Op Cache thành dual-port có thể là để duy trì pipeline dual fetch tốt hơn
Các bài báo liên quan được nhắc tới
- “Multiple-block ahead branch predictors” by Seznec et al. – ASPLOS 1996: trình bày lý do và hướng triển khai của bộ dự đoán nhánh 2-Ahead
- “Optimization of Instruction Fetch Mechanisms for High Issue Rates” by Conte et al. – ISCA 1995: bàn về tối ưu cơ chế instruction fetch cho issue rate cao
- “Increasing the instruction fetch rate via multiple branch prediction and a branch address cache” by Yeh et al. – ICS 1993: bàn về việc tăng fetch rate bằng multiple branch prediction và branch address cache
- “Out-of-Order Instruction Fetch using Multiple Sequencers” by Oberoi and Sohi – ICPP’02: bàn về instruction fetch out-of-order dùng multiple sequencer
- “Parallelism in the Front-End” by Oberoi and Sohi – ISCA 2003: bàn về tính song song trong frontend CPU
1 bình luận
Ý kiến trên Hacker News
Một bài viết giải thích tốt về dự đoán nhánh từ các triển khai ban đầu là https://danluu.com/branch-prediction/
[0]: https://www.youtube.com/watch?v=nhXevKMm3JI&list=PLzH6n4zXuc...
[1]: https://www.youtube.com/watch?v=nczJ58WvtYo&list=PLzH6n4zXuc...
Tò mò hiệu năng SMT sẽ ra sao, và kỳ vọng cách tiếp cận lần này sẽ mang lại lợi ích rồi được tinh chỉnh thêm ở thế hệ sau
Zen5c lên tới 192 lõi hoặc 384 vCPU, còn Zen 6c năm sau có lẽ sẽ đạt 256 lõi. Với máy chủ 1U hai socket, tiềm năng là 512 lõi, 1024 vCPU
Những vấn đề mở rộng web app từng gặp vào năm 2014 giờ có thể nhét vào một máy chủ duy nhất, miễn là làm mát được. Chỉ tính 1 RPS cho mỗi vCPU cũng là 1000 RPS, chưa kể cache hit, trong khi trang chủ HN cũng không dồn 1000 lượt xem trang mỗi giây vào máy chủ
Tò mò hiệu năng HPC sẽ thế nào. Bản thân việc làm mát có thể không phải vấn đề lớn, nhưng đến một lúc nào đó cũng có thể trở thành vấn đề “ướt” cần làm mát chất lỏng trực tiếp (DLC)
Nếu coi một rack máy chủ dày đặc gắn GPU là một máy duy nhất, thì đã đạt tới hàng trăm kilocore rồi
Từng tranh luận với một người không hiểu khái niệm rằng có thể cung cấp dịch vụ ở quy mô Wikipedia từ một máy chủ duy nhất, khá thú vị. Thực ra việc đó đã dễ làm từ một thời gian rồi, chỉ là vì các lý do thực tế như tính sẵn sàng hay hiệu quả chi phí mà người ta không làm vậy
Theo trực giác, khi có thêm các tác vụ xử lý cùng một vấn đề ở nửa tốc độ, đáng lẽ phải có chi phí sử dụng bộ nhớ; tôi tự hỏi liệu có phổ biến các ứng dụng bật SMT thì chỉ dùng thêm bộ nhớ mà không tăng tốc hay không
Trong khá nhiều benchmark công khai, phần lớn ứng dụng dường như không đạt được lợi ích đáng kể về tốc độ thực thi
Luôn thú vị khi thấy một bài báo đã vài chục năm tuổi, lúc công bố không được chú ý nhiều, bỗng trở thành tối tân khi phần cứng đủ mạnh
Ví dụ có Z-buffer. Nó được dùng trong game 3D, nhưng khi xuất hiện trong bài báo đầu tiên, nó chỉ được nhắc như một nhánh phụ vì không phải chủ đề chính và cần quá nhiều bộ nhớ
Vài chục năm sau, megabyte đã khá rẻ, và cuối cùng mọi trình render 3D thời gian thực đều dùng nó
Có vẻ trong tài liệu học thuật đã có khoảng trống chừng 38 năm cho đến khi David MacKay tái phát hiện nó
Lần sử dụng phổ biến đầu tiên là năm 2003, và hiện nay nó được dùng trong WiFi, Ethernet, 5G
[1] https://en.wikipedia.org/wiki/Low-density_parity-check_code
[2] https://scholar.google.com/scholar?q=%22low+density+parity+c...
Vào thư viện và đọc những gì các nhà nghiên cứu khoa học máy tính từng công bố trên giấy, có thể sẽ có những ý tưởng khi đó không thực tế nhưng giờ có thể triển khai được
Trong 20 năm qua, hiệu năng đơn lõi đã bị kìm lại vì ưu tiên mở rộng theo chiều ngang, tức là nhiều lõi hơn, nên độ phức tạp và diện tích die của từng lõi trở thành vấn đề. Nếu không có xu hướng này và các nhà thiết kế CPU chủ yếu theo đuổi hiệu năng đơn lõi, có lẽ ta đã thấy triển khai này sớm hơn nhiều
Z-buffer là một khái niệm đơn giản nên trong bài báo nó có vẻ chỉ như phần phụ. Ví dụ tốt hơn có thể là ray tracing. Dù không có nền tảng đồ họa 3D, bản thân khái niệm khá rõ ràng, nhưng cho tới gần đây vẫn không thực tế về mặt hiệu năng cho render thời gian thực
Điều thú vị là ta không tìm được cách tiếp cận đơn giản hơn để xấp xỉ render giống thực tế, mà phải quay lại một giải pháp cũ, hơi ngây thơ và đắt đỏ
Nhiều học giả cho rằng hệ thống kiểu con cấu trúc về cơ bản đã bị garbage collection lấn át đến chết, nhưng Rust đã hồi sinh nó bằng cách kết hợp với các ý tưởng mới của C++ thời đó
Yêu cầu băng thông bộ nhớ bổ sung này khiến việc triển khai đúng trở nên khó và đắt. Các triển khai cao cấp dùng kênh RAM chuyên dụng, nhưng trên phần cứng giá rẻ, nó chiếm nhiều băng thông của giao diện bộ nhớ dùng chung
Ví dụ, một số game N64 đã tắt Z-buffer và tối ưu việc vẽ nền/tiền cảnh do phần mềm quản lý để tránh chi phí đọc và cập nhật thông tin độ sâu
Bộ dự đoán suy đoán từng là mục tiêu của nhiều cuộc tấn công nhằm trích xuất dữ liệu riêng tư
Nếu khá nhiều ISA phổ biến đều dễ bị ảnh hưởng, tôi tự hỏi liệu có biện pháp nào đang được thực hiện để giảm tác động của những cuộc tấn công như vậy không
Không có cách nào để ngăn chuyện này, trừ một cách tiếp cận ở mức “đun sôi cả đại dương”[0]. Thực thi suy đoán quá có giá trị đối với hiệu năng, đến mức máy tính không có nó gần như hoàn toàn không dùng được. Nếu thật sự muốn một bộ xử lý không có thực thi suy đoán, hãy mua một chiếc Pentium thế hệ 1 đời cũ
Có nhiều biện pháp giảm thiểu thực tế, nhưng tối thiểu phải bảo đảm tách biệt tiến trình giữa tiến trình nạn nhân có bí mật và kẻ tấn công tiềm năng có thể tác động đến quá trình thực thi của nạn nhân
Intel từng bị bắt lỗi vì thực thi suy đoán xuyên qua các ring, nên từ user space có thể đọc được bộ nhớ kernel hoặc hypervisor. Với một CPU được thiết kế không tệ, thứ chủ yếu cần lo là HTML iframe
Các nguồn gốc khác nhau không thể tùy ý gửi HTTP request[1], nhưng có thể nhúng lẫn nhau mà không cần cho phép[2]. Theo truyền thống, thông tin đó được tải vào tiến trình của kẻ tấn công và có thể bị rò rỉ bằng tấn công định thời
Giải pháp ban đầu của web không phải là tách tiến trình cho iframe, mà là loại bỏ hẳn đa luồng dùng chung bộ nhớ. Nếu tước đi chuẩn thời gian của kẻ tấn công, việc nạn nhân thực thi suy đoán gì sẽ ít quan trọng hơn. Nhưng để làm vậy thì phải loại bỏ đa luồng. Nếu không, một thread có thể liên tục ghi dữ liệu đã biết trong vòng lặp để tạo ra đồng hồ
[0] https://hackaday.com/2013/08/02/the-mill-cpu-architecture/
[1] Ít nhất là không thể, trừ khi nguồn đích cho phép bằng CORS
[2] Ví dụ: hotlink hình ảnh hoặc nhúng iframe
Đây không phải là lỗ hổng cố hữu của bản thân việc dự đoán
Với người mới trong lĩnh vực này, đọc bài xong vẫn không rõ chính xác bộ dự đoán rẽ nhánh 2-ahead là gì
Thập niên 90 thường gần với một trong hai kiểu đó, nhưng các bộ xử lý hiện đại dường như hầu hết có cả hai
Tóm tắt của “Multiple-block ahead branch predictors” mô tả đây là cách không dùng thông tin của khối lệnh hiện tại để dự đoán địa chỉ khối lệnh tiếp theo, mà dự đoán khối sau đó nữa. Cách này giảm nút thắt lấy lệnh trong các bộ xử lý “brainiac” có dispatch rộng, và có thể dự đoán hiệu quả hai địa chỉ khối lệnh trong một chu kỳ
Ngoài ra, với các bộ xử lý “speed demon”, nó cho phép pipeline hóa quá trình dự đoán rẽ nhánh để đạt xung nhịp cao hơn hoặc cải thiện độ chính xác nhờ cấu trúc dự đoán lớn hơn. Khác với phương pháp dùng nhiều bộ dự đoán truyền thống, bộ dự đoán rẽ nhánh nhìn trước nhiều khối có thể dùng bất kỳ phương pháp dự đoán rẽ nhánh nào
[0] https://dl.acm.org/doi/10.1145/237090.237169
Nói thêm, có vẻ eyegor đã đăng link rồi, nhưng ý là ít nhất hãy đọc phần tóm tắt
Chắc sẽ khó hơn nhiều so với dự đoán nhánh tiếp theo, nhưng cho phép lấy mã để nuôi pipeline sâu sớm hơn rất nhiều
Vì vậy, thay vì chỉ đánh giá trước n+1 như dự đoán rẽ nhánh thông thường, nó có thể đánh giá trước cả kết quả n+2. Tôi không rõ điều này hoạt động thế nào mà không phá hỏng L1 cache
Nếu là cách nhìn trước xa hơn n+1 thì có vẻ việc đẩy dữ liệu khỏi cache sẽ tăng lên nhiều, nên có lẽ tôi đang bỏ sót điều gì đó
Zen 5 được cho là có thể nhìn xa hơn tới luồng lệnh sau taken branch thứ hai, và nhờ đó có 3 cửa sổ dự đoán hữu ích để tạo ra các lệnh cần decode
Bài báo gốc có thể truy cập công khai, nhưng tôi vẫn chưa đọc được nhiều: https://dl.acm.org/doi/10.1145/237090.237169
Mỗi hướng của nhánh dẫn đến phần bắt đầu của một khối lệnh mới, và lệnh cuối của những khối như vậy thường lại là một nhánh khác
Nói cách khác, bộ dự đoán rẽ nhánh là thiết bị đoán địa chỉ của khối tiếp theo. Bộ dự đoán rẽ nhánh 2-ahead cũng làm việc tương tự, nhưng thực hiện cho hai khối theo sau
Theo cách diễn đạt của bài báo, “thông tin của khối lệnh hiện tại được dùng để dự đoán địa chỉ của khối nằm sau khối lệnh tiếp theo”
Khác với bộ dự đoán rẽ nhánh thông thường, việc này có thể thực hiện mà không cần chờ đến khi lệnh của khối tiếp theo được decode. Vì vậy nó có thể cấp dữ liệu đồng thời cho nhiều bộ decode lệnh
Điều này đặc biệt hữu ích trong các CPU hiện đại, nơi bộ decode lệnh đã trở thành nút thắt. Một bộ decode chỉ decode 1 lệnh mỗi chu kỳ khó có thể theo kịp front-end rộng có thể thực thi nhiều lệnh, chẳng hạn 4~6 lệnh mỗi chu kỳ
Có lẽ cần thêm branch hint: https://github.com/ziglang/zig/issues/5177
Tôi tự hỏi liệu có thể dùng cold, warm, warmer và bỏ qua hot vì đó là mặc định không. Đôi khi cũng có thể đánh dấu tất cả các nhánh là cold trừ một nhánh
Có thể đây là một ý tưởng tệ, nhưng tôi muốn biết lý do
Khi có một nhánh có điều kiện, tôi thắc mắc vì sao không thể lấy và chuẩn bị cả lệnh của hai nhánh có thể xảy ra, rồi bỏ nhánh sai đi
Tôi muốn biết việc đó khó hơn nhiều, hay có lý do nào khác khiến nó không đáng làm
Các bộ dự đoán rẽ nhánh TAGE hiện đại đúng hơn rất nhiều so với 99%. Vì vậy các lệnh bổ sung ở nhánh còn lại hầu như luôn bị vứt bỏ
Tệ hơn nữa, front-end lấy trước hàng chục nhánh so với điểm mà back-end có thể xác nhận hướng thực tế. Đến nhánh tiếp theo thì làm gì? Decode 4 nhánh khả dĩ, rồi tiếp nữa là decode 8, 16, 32 nhánh sao? Phần lớn sẽ bị bỏ đi
Nếu có phần cứng để lấy nhiều luồng lệnh song song, như Intel Gracemont/Goldmont/Skymont và AMD Zen 5, chiến lược tốt hơn là giả định bộ dự đoán rẽ nhánh đúng 100%. Đi theo một nhánh, rồi tiếp tục đi theo nhánh kế tiếp
Intel Skymont có 3 decoder, mỗi decoder 3-wide, nên decode song song 3 mục tiêu nhánh tiếp theo. Intel thậm chí còn chèn các nhánh giả để chia nhỏ các khối mã lớn, sao cho ba decoder luôn decode các phần khác nhau của luồng lệnh sắp tới. Sau đó họ hợp nhất 3 luồng vi thao tác để Skymont duy trì băng thông decode hiệu dụng 9 lệnh mỗi chu kỳ
Thực thi cả hai nhánh chỉ giảm chút độ trễ trong trường hợp hiếm khi dự đoán nhánh sai. Trong khi đó, nếu tiếp tục đi theo hai hoặc ba dự đoán kế tiếp theo một hướng, Intel và AMD có thể khiến nhiều decoder làm việc song song. Intel có thể tạo 9-wide bằng 3 decoder 3-wide đơn giản hơn, còn AMD có thể tạo 8-wide bằng 2 decoder 4-wide đơn giản hơn
Compiler, runtime, CPU, v.v. thường có thể đoán đúng kết quả nào có khả năng hơn, và ngay từ đầu không làm thêm việc thường là chiến lược tốt hơn. Tốt hơn là dùng silicon và nhiệt cho câu trả lời sai để phòng khi đoán nhầm
Có vẻ nhiều người không có trực giác về việc dự đoán rẽ nhánh có thể chính xác đến mức nào. Chỉ cần nhìn vào mã của chính mình cũng nhanh chóng nhận ra: “phần lớn luồng điều khiển sẽ đi hướng này, còn nhánh này là để xử lý trường hợp ngoại lệ”
Compiler ngày nay cũng suy luận điều này khá tốt, và CPU/JIT/runtime cũng có thể xây dựng các heuristic ấn tượng. Dù vậy, khi chúng thất bại, có thể đưa hint tường minh vào mã để báo cho compiler và các thành phần khác hướng kỳ vọng
Bộ đệm tái sắp xếp lệnh của CPU hiện đại sâu tới hàng trăm lệnh, và chỉ cần trong đó có 8 lệnh nhảy có điều kiện thì chương trình đã có 256 đường đi khả dĩ
Nếu xác suất bộ dự đoán rẽ nhánh đoán đúng cả 8 cái vượt 50%, mà thực tế là vậy, thì làm gấp 256 lần công việc để phòng bị là không đáng
Cần silicon để lưu nhiều trạng thái vi kiến trúc hơn, và cần nhiều đơn vị thực thi hơn để tận dụng hoàn toàn kỹ thuật đó. Nhưng CPU superscalar vốn đã cần và có những thứ đó để khai thác song song mức lệnh trong mã ít nhánh
Phần còn lại là công việc đau đầu xử lý các thứ phức tạp như aliasing, interrupt, nhưng các kỹ sư phần cứng giống như phù thủy nên họ cũng làm được
Tuy nhiên, thực thi suy đoán mở ra khả năng lạm dụng kênh phụ timing của cache để rút thông tin từ dữ liệu mà mã chỉ được thực thi suy đoán và các tác dụng phụ về mặt kiến trúc chưa được commit đã chạm tới. Nói cách khác, thông tin có thể rò rỉ ngay cả từ mã không “thực sự” được thực thi
Điều này bao gồm cả mã vốn không được thực thi tường minh do kiểm tra điều kiện, chẳng hạn kiểm tra quyền
Ví dụ tấn công quen thuộc là Spectre: https://en.m.wikipedia.org/wiki/Spectre_(security_vulnerabil...
Vì vậy về cơ bản hoàn toàn không đáng. Tài nguyên chip đó tốt hơn nhiều nếu dùng cho thread hoặc core khác
Để đánh giá đây có phải ý tưởng hay không, trước hết tôi muốn xem dữ liệu hiệu năng. Cũng không có thông tin về penalty dự đoán rẽ nhánh của cách tiếp cận này
Dù sao, trực giác của cách tiếp cận này dường như nằm ở việc tích cực lấy và decode các lệnh có thể chưa có trong L1 instruction cache hoặc micro-op cache
Điều này quan trọng với x86, và có lẽ cả RISC-V. Cả hai đều có độ dài lệnh thay đổi, nên chỉ nhìn vào block instruction cache thì core không biết phải decode các lệnh trong block đó như thế nào. Với cả hai ISA, để bắt đầu decode một block instruction cache, ít nhất phải biết PC của một lệnh
Vì vậy nếu biết ứng dụng có thể nhảy tới đâu ở cách hai block phía trước, điều đó giúp lấy và decode xa hơn so với cách hiện tại
Cách tiếp cận này giống instruction prefetching, nhưng instruction prefetching không cung cấp thông tin điểm bắt đầu cho core
Các core ARM hiệu năng cao có lẽ không gặp vấn đề “tìm điểm bắt đầu” vì mọi lệnh đều dài 32-bit. Do đó ngay cả khi không biết điểm bắt đầu, chúng vẫn có thể thực hiện quy trình decoding song song
Phương pháp này có vẻ mang lại lợi ích cho các ứng dụng nặng front-end, chẳng hạn workload cloud có các khối mã nóng rải rác khắp binary. Tôi tò mò liệu với các loại ứng dụng khác có lợi hay hại về hiệu năng không
Tôi vẫn hoàn toàn không hiểu bộ dự đoán rẽ nhánh 2-ahead là gì
Nhìn chung, các bài nghiên cứu cũ giả định độc giả biết ít hơn nhiều về những chủ đề như thế này. Vì vào thời đó, kiến thức này còn ngách hơn nhiều
Giờ thứ cần thiết là băng thông bộ nhớ. Hai kênh bộ nhớ của socket AM5 dành cho người dùng phổ thông trông khá khiêm tốn so với mức hiệu năng tính toán này, đặc biệt ngay cả khi so với Apple Silicon cơ bản
Tôi đã chuyển từ một cấu hình Zen nặng đô sang M2 Max, và lại một lần nữa ngạc nhiên vì mức tăng băng thông bộ nhớ có thể tăng tốc các tác vụ dữ liệu chuyên sâu đến thế nào. Ngay cả khi đa nhiệm khá nặng, đường ống bộ nhớ hẹp của cấu hình Zen cũng thường xuyên bị nghẽn
Lý do mọi người chú ý đến Apple Silicon, đặc biệt là vì LLM, là LLM tuy phù hợp với GPU hơn nhưng cũng cần nhiều VRAM, trong khi NVIDIA định giá các GPU có nhiều VRAM ở mức vô lý
Nếu AMD thật sự muốn kìm hãm đà tiến của NVIDIA, họ cần bán GPU tiêu dùng có 64~128GB VRAM