3 điểm bởi GN⁺ 2024-07-29 | 1 bình luận | Chia sẻ qua WhatsApp
  • SMT là kỹ thuật trong đó một lõi CPU phát hành lệnh từ nhiều luồng trong cùng một chu kỳ, nhằm lấp đầy hơn các tài nguyên thực thi bị bỏ trống khi chỉ dựa vào song song ở mức lệnh
  • Hyper-Threading của Intel là cách triển khai hai luồng trên mỗi lõi; bằng cách nhân bản trạng thái kiến trúc, hệ điều hành nhìn thấy một lõi vật lý như hai bộ xử lý logic
  • Trong triển khai thực tế, không phải mọi tài nguyên đều đơn giản được tăng gấp đôi; instruction pointer, ITLB, RAT được nhân bản, trace cache và TLB được chia sẻ, còn uop queue, thanh ghi vật lý và reorder buffer được chia đều
  • Mức tăng hiệu năng tùy thuộc vào workload: nếu hai luồng cạnh tranh cache thì có thể chậm hơn, còn các luồng cộng tác trao đổi dữ liệu có thể nhanh hơn nhờ cache dùng chung
  • Tài nguyên dùng chung và thực thi suy đoán có thể dẫn đến lỗ hổng bảo mật, vì vậy trong môi trường nhạy cảm về bảo mật hoặc với workload cần hiệu năng tối đa/độ trễ thấp nhất, tắt SMT là một lựa chọn thực tế

Vì sao cần SMT

  • Các bộ xử lý hiện đại có hàng trăm thanh ghi, nhiều đơn vị load/store và đơn vị số học; để tận dụng chúng, chúng dùng các kỹ thuật song song ở mức lệnh như pipelining, kiến trúc superscalar và thực thi ngoài thứ tự
  • Pipeline chia việc thực thi lệnh thành nhiều giai đoạn và chuyển lệnh sang giai đoạn tiếp theo ở mỗi chu kỳ; với pipeline sâu 5 tầng, sau chu kỳ thứ 5 có thể có tối đa 5 lệnh cùng được xử lý đồng thời
  • Bộ xử lý superscalar có thể phát hành nhiều lệnh trong một chu kỳ, và các bộ xử lý Intel Core i7 gần đây có thể phát hành 4 lệnh trong một chu kỳ
  • Trong chương trình thực tế, khó tìm đủ các lệnh độc lập, khiến tài nguyên thực thi có lúc bị bỏ trống
    • Lãng phí ngang xảy ra khi trong một luồng không tìm được đủ lệnh độc lập để lấp đầy issue width
    • Lãng phí dọc xảy ra khi các lệnh tiếp theo phụ thuộc vào lệnh đang thực thi, khiến không thể phát hành lệnh nào trong một chu kỳ
  • Đa luồng truyền thống chỉ phát hành lệnh của một luồng ở mỗi chu kỳ rồi chuyển sang luồng khác ở chu kỳ tiếp theo, nên có thể giảm lãng phí dọc, nhưng lãng phí ngang và chi phí chuyển ngữ cảnh vẫn còn
  • SMT phát hành lệnh từ nhiều luồng trong cùng một chu kỳ mà không cần chuyển ngữ cảnh, nhờ đó lấp đầy tài nguyên thực thi với tỷ lệ cao hơn
  • Cách triển khai SMT của Intel, Hyper-Threading, bị giới hạn ở hai luồng trên mỗi lõi

Cấu trúc cơ bản của SMT kiểu Intel

  • Bộ xử lý không hỗ trợ SMT thông thường chỉ có thể thực thi lệnh của một luồng tại một thời điểm
  • Mỗi luồng có trạng thái kiến trúc, bao gồm giá trị thanh ghi, program counter, thanh ghi điều khiển, v.v.
  • Để thực thi đồng thời lệnh của hai luồng, phải biểu diễn đồng thời trạng thái của cả hai luồng, nên triển khai SMT nhân bản trạng thái kiến trúc của bộ xử lý
  • Do sự nhân bản này, một bộ xử lý vật lý hiện ra với hệ điều hành như hai bộ xử lý logic, và hệ điều hành có thể lập lịch luồng cho từng bộ xử lý logic
  • Các buffer và tài nguyên thực thi ở mức vi kiến trúc được nhân bản, chia sẻ hoặc phân chia tùy theo các yếu tố như chi phí, điện năng và diện tích chip
  • Phạm vi thảo luận chủ yếu là cách triển khai SMT của Intel, dựa trên sách trắng năm 2002 của Intel

Ba phần của vi kiến trúc CPU

  • Bộ xử lý cung cấp ISA cho lập trình viên như một giao diện công khai; ISA bao gồm tập lệnh và các thanh ghi mà lệnh có thể sử dụng
  • Vi kiến trúc là phần triển khai nội bộ, có thể khác nhau giữa các mẫu bộ xử lý hỗ trợ cùng một ISA
  • Vi kiến trúc của bộ xử lý hiện đại được chia thành ba phần lớn
    • Front-end: bao gồm đơn vị điều khiển lệnh, có nhiệm vụ lấy và giải mã lệnh chương trình sẽ thực thi tiếp theo
    • Back-end: bao gồm các tài nguyên thực thi như thanh ghi vật lý, đơn vị số học, đơn vị load/store; phân bổ tài nguyên cho lệnh đã giải mã và lập lịch thực thi
    • retirement unit: phản ánh kết quả của các lệnh đã thực thi vào trạng thái kiến trúc của bộ xử lý một cách cuối cùng

SMT ở front-end

  • Instruction pointer theo dõi địa chỉ của lệnh sẽ được lấy tiếp theo
    • Bộ xử lý hỗ trợ SMT có hai bộ instruction pointer để theo dõi độc lập lệnh tiếp theo của hai chương trình
  • trace cache lưu các trace lệnh đã giải mã gần đây, giúp giảm chi phí giải mã và độ trễ thực thi của các lệnh được lặp lại
    • Hai bộ xử lý logic chia sẻ động theo nhu cầu
    • Nếu một luồng thực thi nhiều lệnh hơn, nó có thể chiếm nhiều entry hơn trong trace cache
    • Mỗi entry được gắn tag bằng thông tin luồng để phân biệt lệnh của hai luồng
    • Việc truy cập trace cache được phân xử giữa hai bộ xử lý logic ở mỗi chu kỳ
  • Khi trace cache miss, front-end tìm lệnh ở địa chỉ đó trong L1 instruction cache; nếu L1 instruction cache miss, phải lấy từ tầng cache tiếp theo hoặc bộ nhớ chính
  • L1 instruction cache cache dữ liệu theo địa chỉ ảo, nhưng truy cập bộ nhớ chính cần địa chỉ vật lý
  • ITLB chứa các địa chỉ ảo đã được chuyển đổi gần đây để chuyển địa chỉ ảo thành địa chỉ vật lý
    • Trong bộ xử lý hỗ trợ SMT, mỗi bộ xử lý logic có ITLB cache riêng
    • Logic lấy lệnh từ bộ nhớ chính hoạt động theo cơ chế ai đến trước phục vụ trước, nhưng dành riêng ít nhất một slot yêu cầu cho mỗi bộ xử lý logic để cả hai đều có thể tiến triển
    • Lệnh đến từ bộ nhớ chính được lưu trong một streaming buffer nhỏ trước khi giải mã; trong bộ xử lý hỗ trợ SMT, buffer này cũng được nhân bản theo từng bộ xử lý logic
  • Sau khi được lấy, lệnh được giải mã thành các uop nhỏ hơn và đơn giản hơn
    • uop đi vào uop queue, đóng vai trò ranh giới giữa front-end và back-end của CPU
    • uop queue được chia đều giữa hai bộ xử lý logic; cách phân chia tĩnh này giúp hai bộ xử lý logic tiến triển độc lập

SMT ở back-end

  • Back-end lấy các vi lệnh từ uop queue để thực thi, nhưng không chỉ bị ràng buộc theo thứ tự chương trình gốc mà thực hiện thực thi ngoài thứ tự
  • Các lệnh chương trình gần nhau thường phụ thuộc lẫn nhau; nếu có tác vụ độ trễ dài như đọc bộ nhớ chính, các lệnh phụ thuộc cũng phải chờ
  • Động cơ thực thi ngoài thứ tự thực thi các lệnh phía sau sớm hơn thứ tự gốc để giảm lãng phí tài nguyên
  • allocator xác định các tài nguyên cần thiết cho vi lệnh và phân bổ dựa trên mức độ sẵn có
    • Trong một chu kỳ, nó phân bổ tài nguyên cho vi lệnh của một bộ xử lý logic, rồi ở chu kỳ tiếp theo chuyển sang bộ xử lý logic kia
    • Nếu uop queue chỉ có vi lệnh của một bộ xử lý logic, hoặc nếu một bộ xử lý logic đã dùng hết phần tài nguyên của mình, allocator dùng toàn bộ chu kỳ cho bộ xử lý logic còn lại
  • Các tài nguyên chính của back-end là sự pha trộn giữa nhân bản, chia sẻ và phân chia
    • Ở mức ISA, X86-64 chỉ có 16 thanh ghi số nguyên đa dụng, nhưng ở mức vi kiến trúc có hàng trăm thanh ghi số nguyên vật lý và số thanh ghi dấu phẩy động tương tự
    • Trong bộ xử lý hỗ trợ SMT, các thanh ghi vật lý được chia đều cho hai bộ xử lý logic
    • Load buffer và store buffer dùng cho các thao tác đọc/ghi bộ nhớ cũng được chia đều cho hai bộ xử lý logic

Đổi tên thanh ghi, lập lịch và commit

  • Để thực thi ngoài thứ tự, back-end thực hiện đổi tên thanh ghi
    • Vì ở mức ISA có ít thanh ghi kiến trúc, lệnh chương trình tái sử dụng cùng một thanh ghi trong nhiều lệnh độc lập
    • Động cơ thực thi ngoài thứ tự thay thanh ghi logic ban đầu bằng một trong các thanh ghi vật lý, cho phép thực thi song song với những lệnh trước đó
    • Ánh xạ này được duy trì trong register alias table, tức RAT
    • Hai bộ xử lý logic mỗi bên có bộ thanh ghi kiến trúc riêng, nên RAT cũng có bản sao riêng cho từng bên
  • Các lệnh sau giai đoạn register renaming và allocator đi vào hàng đợi sẵn sàng
    • Một hàng đợi dành cho lệnh đọc/ghi bộ nhớ, hàng còn lại dành cho lệnh thông thường
    • Trên lõi hỗ trợ SMT, các hàng đợi này được chia đều cho hai bộ xử lý logic
  • Bộ xử lý có nhiều instruction scheduler chạy song song
    • Ở mỗi chu kỳ CPU, một phần lệnh trong hàng đợi sẵn sàng được chuyển tới scheduler
    • Hàng đợi gửi lệnh của một bộ xử lý logic trong một chu kỳ, rồi chuyển sang bộ xử lý logic kia ở chu kỳ tiếp theo
    • Scheduler không quan tâm đến bộ xử lý logic; nó lập tức gửi đi thực thi các vi lệnh có toán hạng và đơn vị thực thi cần thiết đã sẵn sàng
    • Để đảm bảo công bằng, có giới hạn về số active entry mà một bộ xử lý logic có thể có trong scheduler queue
  • Kết quả của lệnh đã thực thi được đưa vào reorder buffer
    • Dù lệnh được thực thi ngoài thứ tự, chúng phải được commit vào trạng thái kiến trúc của bộ xử lý theo đúng thứ tự chương trình gốc
    • Trên lõi hỗ trợ SMT, reorder buffer được chia đều cho hai bộ xử lý logic
  • Retirement unit theo dõi liệu lệnh đã sẵn sàng commit vào trạng thái kiến trúc hay chưa và retire chúng theo đúng thứ tự chương trình
    • Trên lõi hỗ trợ SMT, nó luân phiên xử lý giữa các vi lệnh của từng bộ xử lý logic
    • Nếu một bộ xử lý logic không có vi lệnh nào cần retire, toàn bộ băng thông được dùng cho bộ xử lý logic kia
    • Sau khi lệnh retire, có thể cần ghi vào L1 cache; logic chọn thao tác ghi này cũng luân phiên giữa hai bộ xử lý logic ở mỗi chu kỳ

Phân hệ bộ nhớ và tác động của cache

  • TLB, dùng để chuyển địa chỉ ảo của yêu cầu dữ liệu thành địa chỉ vật lý, được hai bộ xử lý logic chia sẻ động theo nhu cầu
  • Các entry TLB được gắn tag bằng logical processor id để phân biệt mục của hai bộ xử lý logic
  • Mỗi lõi CPU có private L1 cache riêng
  • L2 cache có thể là private hoặc được chia sẻ giữa các lõi, tùy vi kiến trúc
  • Nếu có L3 cache, nó được chia sẻ giữa các lõi
  • Cache không nhận biết sự tồn tại của bộ xử lý logic
  • Vì L1 cache và trong một số trường hợp L2 cache là private theo lõi, chúng cùng chứa dữ liệu của hai bộ xử lý logic khi cần
    • Nếu hai luồng dùng cache một cách quyết liệt, có thể xảy ra xung đột dữ liệu và eviction, làm giảm hiệu năng
    • Nếu hai luồng làm việc trên cùng một tập dữ liệu, cache dùng chung có thể cải thiện hiệu năng

Tiêu chí lựa chọn về hiệu năng và bảo mật

  • Ngay cả khi chỉ chạy một luồng trên lõi hỗ trợ SMT, nhiều buffer và tài nguyên thực thi vẫn ở trạng thái được chia sẻ hoặc phân chia giữa hai bộ xử lý logic, có thể làm giảm hiệu năng tiềm năng của luồng đơn
  • Trên bộ xử lý logic không được sử dụng, hệ điều hành chạy idle loop; vòng lặp này cũng có thể tiêu thụ tài nguyên mà bộ xử lý logic kia có thể dùng để đạt hiệu năng tối đa
  • Trên các bộ xử lý Intel Core, khi chỉ có một luồng chạy trên một lõi, dường như không có việc chia sẻ hay phân chia tài nguyên; Intel xem đây là cải tiến được đưa vào ở thế hệ đó
  • Khi hai luồng chạy trên hai bộ xử lý logic của một lõi hỗ trợ SMT, mẫu truy cập cache quyết định hiệu năng
    • Nếu hai luồng cạnh tranh cache, chúng sẽ eviction dữ liệu của nhau và làm giảm hiệu năng
    • Nếu chúng cộng tác, chẳng hạn một luồng tạo dữ liệu và luồng kia tiêu thụ dữ liệu đó, việc chia sẻ dữ liệu trong cache sẽ cải thiện hiệu năng
    • Nếu hai luồng không dùng cache theo kiểu cạnh tranh, chúng có thể tăng mức sử dụng tài nguyên lõi CPU mà không cản trở hiệu năng của nhau
  • Nhiều chuyên gia cho rằng với các chương trình cần hiệu năng tối đa tuyệt đối, nên tắt SMT để một luồng đơn có thể dùng toàn bộ tài nguyên
  • SMT cũng đi kèm vấn đề bảo mật
    • Do tài nguyên dùng chung và thực thi suy đoán, có thể mở ra khả năng dữ liệu nhạy cảm bị rò rỉ cho kẻ tấn công
    • Tài liệu của Oracle Linux và Red Hat được liên kết như các ví dụ về vấn đề bảo mật liên quan đến SMT
    • Khuyến nghị chung là tắt SMT trên hệ thống
    • Cũng có tin đồn rằng Intel có thể loại bỏ Hyper-Threading trong thế hệ bộ xử lý tiếp theo, Arrow Lake

Tài liệu tham khảo

1 bình luận

 
GN⁺ 2024-07-29
Ý kiến trên Hacker News
  • Nếu hiểu SMT theo cách cực kỳ đơn giản, thì điểm dễ cảm nhận là trong lúc một luồng bị dừng vì cache miss, nó vẫn có thể giữ cho ALU quý giá luôn bận rộn
    LPDDR trên laptop ngày xưa chậm hơn và số lõi cũng ít hơn, nên có lẽ giá trị của nó khi đó lớn hơn; còn bây giờ thì cũng có nhiều trường hợp số lõi còn nhiều hơn lượng công việc có thể mở rộng, nên giá trị đó bớt rõ rệt hơn
    Người ta cũng tránh tranh chấp cache bằng cách không xếp công việc lên cùng một lõi với luồng quan trọng, vì biết rằng hiệu năng đơn luồng mới là nút thắt cổ chai
    Trước đây tôi từng thử nghiệm lõi Efficient/Performance và lõi SMT trong dựng hình đa luồng của DirectX 12, và trên i7-12700K thì thời gian render cảnh phức tạp gần như như nhau giữa việc chỉ dùng P-core, dùng P+SMT, hay P+E+SMT. Tuy nhiên, trên Xbox Series X thì cùng bài test đó nhanh hơn đôi chút khi cũng xếp việc lên SMT

    • Render ngay từ đầu đã là một trong những kịch bản mà SMT cho kết quả ngang bằng hoặc chậm hơn. Nó vốn đã có rất nhiều phép toán, nên FPU luôn bận, đặc biệt vì bộ chia là một trong những phép toán đắt đỏ nhất trong bộ xử lý
      SMT phát huy khi chờ I/O hoặc làm các tác vụ số nguyên đơn giản. Nếu cả hai luồng đều có thể làm bão hòa FPU, thì SMT thường sẽ chậm hơn do phần gắn thẻ bổ sung để đánh dấu quyền sở hữu dữ liệu bên trong CPU
    • Hyper-Threading của Intel về cơ bản gần giống một kiểu hack đường ống ghi
      Điểm cốt lõi không hẳn là cache miss, mà là cho phép lõi thực thi việc khác trong khi chờ thao tác ghi hoàn tất
      Vì vậy có đoạn mã mở rộng rất kém, còn có đoạn lại đạt mức tăng tốc gần như tuyến tính
    • Dạo này, nhất là khi tính cả cấp điện từ mặt sau, tôi khá tò mò việc một bộ xử lý bị dừng vì cache sẽ làm giảm throttling nhiệt của chính nó và cả bộ xử lý lân cận đến mức nào
      Có khi cứ để những bộ xử lý này chợp mắt một chút lại tốt hơn
    • Liên quan tới ý LPDDR ngày xưa chậm hơn, điều kỳ lạ là độ trễ thực ra không cải thiện nhiều. Độ trễ CAS của DDR2/3/4/5 phần lớn đều ở mức khoảng 5~10ns
      Độ rộng bus, số lần truyền mỗi giây, hàng đợi, và điện năng cho mỗi bit truyền/lưu trữ đã được cải thiện, nhưng nếu chương trình cần dữ liệu không có trong cache và dự đoán cũng sai, thì rốt cuộc độ trễ RAM vẫn là vấn đề
    • Tôi tự hỏi thay vì SMT, liệu có thể đi theo hướng tạm thời tắt ALU/FPU không dùng đến trong lúc chờ một thứ gì đó ở đầu trước của pipeline, để giảm nhiệt và điện năng tiêu thụ thay vì tối đa hóa mức độ sử dụng hay không
  • CPU Arrow Lake thế hệ tiếp theo của Intel được cho là sẽ loại bỏ hoàn toàn Hyper-Threading, tức SMT
    Mức lợi ích về hiệu năng vốn luôn phụ thuộc rất nhiều vào ứng dụng, nên đơn giản hóa có thể lại tốt hơn
    Có một thảo luận gần đây về khi nào và ở đâu nó thực sự có ý nghĩa tại đây: https://news.ycombinator.com/item?id=39097124

    • Hầu hết chương trình đều sẽ chạm tới giới hạn về số luồng có thể dùng một cách hợp lý. Khi số lõi ít hơn nhiều so với mức đó, SMT có ý nghĩa để tận dụng tài nguyên CPU tốt hơn; nhưng từ thời điểm có đủ lõi trở đi, SMT có thể không còn hợp lý nữa
      Tôi vẫn chưa chắc chúng ta đã thực sự tới điểm đó, nhưng P/E core của Intel là một phương án thay thế hướng tới mục tiêu tương tự, và trên desktop có nhiều tác vụ đơn luồng hoặc ít luồng thì điều này khá hợp lý. Cũng có vẻ có giá trị ở chỗ tối ưu ứng dụng không cần phải xử lý riêng biệt giữa SMT và E-core
      Trong khi đó, AMD dự định trước mắt vẫn chủ yếu giữ lõi đồng nhất và tiếp tục dùng SMT. Rốt cuộc chiến lược nào tốt hơn thật sự còn khác biệt rất lớn tùy ứng dụng, nên khó đánh giá một cách đơn giản
    • Với trường hợp sử dụng cá nhân là làm game và engine, việc cầu nguyện với vị thần xếp luồng CPU để mỗi luồng có lõi riêng của nó lại nhanh hơn Hyper-Threading
      Vì thế tôi quyết định giới hạn số luồng ở std::thread::hardware_concurrency() / 2 - 1, tức số lõi - 1. Tôi đang làm việc với std::vector
    • Theo tiêu chuẩn benchmark phổ biến trong ngành, Intel Hyper-Threading ít nhất là cứ cách một thế hệ thì có một lần chậm hơn so với việc tắt nó
      Ngay cả khi hoạt động tốt thì mức cải thiện cũng chỉ quanh vài chục phần trăm, và từng có giai đoạn các thế hệ liên tiếp còn tệ hơn, nên tôi không hiểu vì sao họ vẫn tiếp tục thử
    • Trên linh kiện máy chủ cũng vậy sao?
  • Mỗi lần đọc về cách những tính năng CPU cấp thấp như thế này hoạt động, tôi lại thấy kinh ngạc
    Hồi đại học tôi có học một môn kiểu như “nhập môn phần cứng máy tính”, nhưng thực ra phải gọi là “nhập môn thiết kế CPU” mới đúng. Chúng tôi tạo bộ cộng, latch, flip-flop từ các cổng logic, và đến cuối kỳ còn có thể thiết kế một bộ xử lý cực kỳ cơ bản ở mức cổng
    Nhưng để nghĩ ra rồi tạo được những thứ như đổi tên thanh ghi hay thực thi ngoài thứ tự thì thật khó hình dung. Những thứ đó cũng được thiết kế ở mức cổng sao? Hay là có một kiểu “trình biên dịch” dùng ngôn ngữ nào đó rồi tự bố trí cổng và transistor?

    • Tôi đã học lớp tiếp theo và có học SMT cùng thêm vài thứ khác
      Tất cả bài tập đều làm bằng Verilog, một ngôn ngữ mô tả phần cứng, nên nhờ đó có thể viết ở mức trừu tượng hóa cao hơn cho nhiều thành phần
  • Một trong những hiểu lầm lớn mà người dùng thường có về SMT là mô hình tinh thần tưởng tượng rằng có một “lõi thật” và một lõi khác kém hơn nó
    Ở mọi khía cạnh có thể quan sát được, hai luồng là tương đương nhau

    • Có lẽ nhận thức đó bắt nguồn từ hiệu năng. Hai luồng có thể làm cùng một công việc, nhưng sẽ không cho hiệu năng gấp đôi như khi có một luồng thứ hai “thật”, tức là có lõi thứ hai
      Rốt cuộc nếu chỉ nhìn từ góc độ hiệu năng, thì về mặt khái niệm nó gần với khoảng 1,25 lõi đơn luồng hơn, hoặc gần với tỷ lệ đó tùy ứng dụng
    • Khi chạy những tác vụ được tối ưu hóa cao và ăn rất nhiều tính toán như nén video, quạt máy tính gào lên như động cơ phản lực mà trình quản lý tác vụ lại hiển thị CPU usage 50%, thì cảm nhận đó cũng dễ hiểu
    • CPU mới của Intel thực sự có cả “P-core” là lõi thật và “E-core” là lõi kém hơn
      Tôi cho rằng lý do chính đưa E-core vào không hẳn là điện năng hay hiệu năng, mà là nhiệt và diện tích die. Vì thế tôi luôn mua chip không có E-core, vì tôi nghĩ như vậy tốt hơn
  • Tôi thắc mắc phải tìm kiếm kiểu bài viết kỹ thuật chi tiết như thế này bằng cách nào.
    Tôi đã thử tìm đúng chủ đề này, nhưng đúng như dự đoán, vì đây là kỹ thuật hướng tới người dùng cuối nên kết quả tìm kiếm chỉ toàn bài viết dành cho người dùng không giải thích ra hồn điều gì

    • Cứ dùng https://hn.algolia.com. Với giả định là phần lớn các bài kiểu này đều được đăng hoặc nhắc tới trên HN
    • Tôi thấy LLM có truy cập web khá hợp với kiểu tìm kiếm này. Ít nhất cũng giúp định hướng.
      Tuy vậy, các URL nó đưa ra thì phần lớn là bịa ra
    • Tôi không biết Google có theo dõi mức tăng đột biến quan tâm đến bài này vì bài HN đó không, nhưng khi tìm “how does simultaneous multi threading work” thì bài blog này hiện ra khoảng kết quả thứ 5 với tôi.
      Tôi kiểm tra trên tab riêng tư Firefox mới ở một thiết bị khác; điều đó không chặn hoàn toàn việc theo dõi hay bộ nhớ đệm, nhưng tôi nghĩ đây là một xấp xỉ khá hợp lý
  • Mô tả rằng “trên lõi CPU có bật SMT, nhiều bộ đệm và tài nguyên thực thi phải được hai bộ xử lý logic chia sẻ, nên ngay cả khi chỉ có một luồng đang chạy trên lõi SMT thì luồng đó cũng không thể dùng các tài nguyên ấy và hiệu năng tiềm năng bị giảm” thì hiện nay không còn đúng nữa.
    Ở chế độ SMT, người ta phân chia ROB, băng thông fetch/decode, v.v., nhưng tôi đã thấy nhiều lõi SMT cho phép dùng toàn bộ các phần đó khi không ở chế độ SMT

    • Dòng bộ xử lý Phi x200 hoạt động đúng như vậy. Ở chế độ không SMT, mỗi luồng có nhiều tài nguyên hơn hẳn so với chế độ SMT 4 chiều
  • Mục đích cốt lõi của SMT là tối đa hóa mức sử dụng của bộ máy thực thi superscalar.
    Tôi tự hỏi liệu xu hướng này có nghĩa là mọi người cho rằng superscalar không còn quan trọng như trước nữa hay không

  • Nhìn chung là một bản tóm tắt tốt, nhưng ở vài chỗ tôi có cảm giác hơi lẫn lộn.
    Tôi muốn biết thêm các bí quyết nghề nghiệp mà người trong ngành dùng, dù chỉ trong phạm vi không liên quan đến bảo mật

  • Kiến trúc Bulldozer tội nghiệp của AMD từng bị chê bai dữ dội vì không có SMT, thế mà giờ mọi người lại đang rời xa SMT.
    Tất nhiên tôi biết Bulldozer có nhiều vấn đề hơn rất nhiều ngoài chuyện thiếu SMT. Trên thực tế nó gần như là cấu trúc ngược lại, nơi nhiều lõi cùng chia sẻ những thứ như ALU. Nhưng nếu hiệu năng của nó được đẩy lên thêm một chút, có lẽ nó đã là một thứ gì đó nhìn thấy trước xu hướng

    • Kiến trúc PowerXX không hề rời xa SMT.
      Power10 hiện hỗ trợ hiệu quả SMT8, tức 8 luồng mỗi lõi, và xét tới việc họ đã nhiều năm liên tục phát triển thiết kế xoay quanh SMT thì tôi không nghĩ họ sẽ từ bỏ nó
  • Điều đáng lưu ý là đơn vị tính toán của GPU cũng thường dùng một mức SMT cỡ 7–10 luồng mỗi CU.
    Cách này giúp che giấu độ trễ

    • Phần lớn GPU không dùng SMT mà dùng tiền thân của nó là đa luồng hạt mịn.
      Ở mỗi chu kỳ xung nhịp, nó chọn và bắt đầu lệnh của luồng nào trong số nhiều luồng khả dụng đang cần các tài nguyên chưa bận. Phần lớn GPU không khởi động nhiều lệnh mỗi xung nhịp, dù nhiều lệnh sau khi khởi động có thể cùng tiến hành đồng thời. Ngay cả khi khởi động nhiều lệnh mỗi xung nhịp, chúng có thể phải thuộc các lớp lệnh riêng biệt dùng các tài nguyên thực thi khác nhau, như lệnh vô hướng và lệnh vectơ.
      SMT, tức đa luồng đồng thời, là cách mà ở mỗi chu kỳ xung nhịp, nhiều lệnh từ mọi luồng đều được khởi động cùng lúc, rồi các lệnh đó cạnh tranh các đơn vị thực thi khác nhau của CPU superscalar để giữ cho càng nhiều đơn vị thực thi càng bận càng tốt. Với mỗi đơn vị thực thi song song, như từng bộ cộng số nguyên trong 6 bộ cộng của CPU hiện đại, hệ thống sẽ quyết định riêng nên chạy lệnh nào từ hàng đợi chứa lệnh của tất cả các luồng đồng thời