sirhung1993
Người qua đường
Ưm, mới check lại https://www.javacodemonk.com/what-is-atomicinteger-class-and-how-it-works-internally-1cda6a56Tăng số lượng thread khi quá số thread của CPU thì không làm tăng số instruction được fetch, nhưng có tác dụng tận dung thời gian rỗi của CPU nếu ứng dụng là I/O bound.
Vì cơ chế của OS là khi gặp I/O thì context-switch sang thread khác, và chỉ dựng dậy khi đã có kết quả.
Tăng quá nhiều thread thì có cái hại là overhead của OS (bao gồm context switch, scheduling, chiếm tài nguyên) có thể lớn hơn lợi ích thu được. Vậy nên người ta mới nghĩ ra coroutine.
Nhưng với ứng dụng CPU bound thì không có tác dụng mà chỉ toàn hại.
Atomic được cài đặt bằng Fence, không liên quan đến SIMD.
Slide này cũng cũ rồi.
CPU ngày nay (khoảng 20 năm nay) ngoài pipeline thì họ sử dụng thêm một kỹ thuật khác gọi là Out-of-order execution (OOO). Tức là các instruction không chỉ bị chia thành nhiều pipeline stage khác nhau, mà việc thực thi các stage còn không theo thứ tự. CPU sẽ tự sắp xếp các các micro-ops (do 1 instruction chia nhỏ thành ở stage decode) rồi lập lịch để thực thi các stage tiếp theo, miễn là đảm bảo không bị conflict về dữ liệu. Thuật toán họ sử dụng để lập lịch là Tomasulo.
Chính vì OOO cho nên cùng một lúc CPU có thể thực thi được nhiều instruction (không conflict nhau). Nhưng nó không phải theo kiểu là số stage == số instruction tối đa. Mà là trong những stage cuối cùng của pipeline sẽ là bước chính thức thực thi micro-ops, việc này được thực hiện bởi các Execution Unit (EU). Số micro-ops tối đa mà CPU thực thi được trong một thời điểm == số ops được Retire (đã tính toán xong kết quả) ~ số EU.
VD đây là kiến trúc Zen 3. Có thể thấy 1 core CPU có đến hơn 14 EU.
![]()
Trong thực tế thì có nhiều lý do nên không thể nào sử dụng hết cùng lúc 14 EU đó được. Một trong số đó là do phụ thuộc về mặt dữ liệu giữa các instruction, một cách để cải thiện là simultaneous multithreading (SMT), phía Intel gọi là Hyper threading (HT), nhờ đó mà có thể cùng lúc có 2, 4, hoặc 8 luồng thực thi, vì các instruction thuộc các luồng khác nhau nên chắc chắn không phụ thuộc nhau về mặt dữ liệu (*), nên hiệu suất sử dụng các EU tăng cao hơn.
(*):dữ liệu đang nói đến ở đây là dữ liệu trên thanh ghi, còn trong memory thì CPU không có cách nào detect được dependency, coder phải dùng một cơ chế gọi là Fence để chỉ thị cho cpu biết thứ tự thực hiện các instruction nên như nào, tránh reorder lung tung.
Dùng combination của volatile + CAS ( đảm bảo atomic operation) , hình như cũng ko dùng Fence


Chờ các pro vào update.