Giả sử các yêu cầu bộ đệm l1 và l2 dẫn đến sai sót, bộ xử lý có bị đình trệ cho đến khi bộ nhớ chính được truy cập không?
Tôi đã nghe về ý tưởng chuyển sang một chủ đề khác, nếu vậy những gì được sử dụng để đánh thức các chủ đề bị đình trệ?
Giả sử các yêu cầu bộ đệm l1 và l2 dẫn đến sai sót, bộ xử lý có bị đình trệ cho đến khi bộ nhớ chính được truy cập không?
Tôi đã nghe về ý tưởng chuyển sang một chủ đề khác, nếu vậy những gì được sử dụng để đánh thức các chủ đề bị đình trệ?
Câu trả lời:
Độ trễ bộ nhớ là một trong những vấn đề cơ bản được nghiên cứu trong nghiên cứu kiến trúc máy tính.
Việc thực hiện đầu cơ với vấn đề hướng dẫn không theo thứ tự thường có thể tìm thấy công việc hữu ích cần thực hiện để lấp đầy độ trễ trong lần truy cập bộ đệm L1, nhưng thường hết công việc hữu ích sau 10 hoặc 20 chu kỳ. Đã có một số nỗ lực để tăng số lượng công việc có thể được thực hiện trong một lần bỏ lỡ thời gian dài. Một ý tưởng là cố gắng thực hiện dự đoán giá trị (Lipasti, Wilkerson và Shen, (ASPLOS-VII): 138-147, 1996). Ý tưởng này rất thời trang trong giới nghiên cứu kiến trúc hàn lâm trong một thời gian nhưng dường như không hoạt động trong thực tế. Một nỗ lực cuối cùng để tiết kiệm dự đoán giá trị từ thùng rác của lịch sử đã được thực hiện runahead(Mutlu, Stark, Wilkerson và Patt (HPCA-9): 129, 2003). Trong thực thi runahead, bạn nhận ra rằng các dự đoán giá trị của mình sẽ sai, nhưng dù sao thì thực hiện theo suy đoán và sau đó loại bỏ tất cả các công việc dựa trên dự đoán, theo lý thuyết rằng ít nhất bạn sẽ bắt đầu một số tìm nạp trước cho những gì sẽ là bộ đệm L2 nhớ Nó chỉ ra rằng runahead lãng phí rất nhiều năng lượng mà nó chỉ không xứng đáng.
Một cách tiếp cận cuối cùng trong tĩnh mạch này có thể nhận được một lực kéo trong ngành liên quan đến việc tạo ra các bộ đệm sắp xếp lại rất dài. Các hướng dẫn được thực hiện theo suy đoán dựa trên dự đoán nhánh, nhưng không có dự đoán giá trị nào được thực hiện. Thay vào đó, tất cả các hướng dẫn phụ thuộc vào tải có độ trễ dài sẽ bỏ lỡ và chờ trong bộ đệm sắp xếp lại. Nhưng vì bộ đệm sắp xếp lại rất lớn, bạn có thể tiếp tục tìm nạp các hướng dẫn nếu bộ dự báo nhánh đang làm một công việc tốt, đôi khi bạn sẽ có thể tìm thấy công việc hữu ích sau này trong luồng hướng dẫn. Một bài báo nghiên cứu có ảnh hưởng trong lĩnh vực này là Đường ống dòng chảy liên tục(Srinivasan, Rajwar, Akkary, Gandhi và Upton (ASPLOS-XI): 107-119, 2004). (Mặc dù thực tế là tất cả các tác giả đến từ Intel, tôi tin rằng ý tưởng đã có thêm lực kéo tại AMD.)
Sử dụng nhiều luồng cho dung sai độ trễ có lịch sử lâu hơn nhiều, với thành công lớn hơn nhiều trong ngành. Tất cả các phiên bản thành công đều sử dụng hỗ trợ phần cứng cho đa luồng. Phiên bản đơn giản nhất (và thành công nhất) của cái này là cái thường được gọi là FGMT ( đa luồng hạt mịn ) hoặc đa luồng xen kẽ . Mỗi lõi phần cứng hỗ trợ nhiều bối cảnh luồng ( ngữ cảnh về cơ bản là trạng thái thanh ghi, bao gồm các thanh ghi như con trỏ lệnh và bất kỳ thanh ghi cờ ẩn nào). Trong bộ xử lý đa luồng hạt mịn, mỗi luồng được xử lý trong-gọi món. Bộ xử lý theo dõi các luồng nào bị đình trệ khi lỡ tải có độ trễ dài và sẵn sàng cho hướng dẫn tiếp theo của chúng và nó sử dụng chiến lược lập lịch trình FIFO đơn giản trên mỗi chu kỳ để chọn luồng sẵn sàng thực hiện chu trình đó. Một ví dụ ban đầu về điều này trên quy mô lớn là bộ xử lý HEP của Burton Smith (Burton Smith đã tiếp tục kiến trúc sư siêu máy tính Tera, cũng là một bộ xử lý đa luồng hạt mịn). Nhưng ý tưởng đi xa hơn nhiều, vào những năm 1960, tôi nghĩ vậy.
FGMT đặc biệt hiệu quả trong việc truyền tải khối lượng công việc. Tất cả các GPU hiện đại (đơn vị xử lý đồ họa) là đa lõi trong đó mỗi lõi là FGMT và khái niệm này cũng được sử dụng rộng rãi trong các lĩnh vực điện toán khác. Sun's T1 cũng là FMGT đa lõi, và Xeon Phi của Intel cũng vậy (bộ xử lý thường được gọi là "MIC" và từng được gọi là "Larabee").
Ý tưởng về Đa luồng đồng thời (Tullsen, Eggers và Levy, (ISCA-22): 392-403, 1995) kết hợp đa luồng phần cứng với thực thi đầu cơ. Bộ xử lý có nhiều bối cảnh luồng, nhưng mỗi luồng được thực hiện theo cách suy đoán và không theo thứ tự. Sau đó, một trình lập lịch phức tạp hơn có thể sử dụng các phương pháp phỏng đoán khác nhau để tìm nạp từ chuỗi có khả năng có công việc hữu ích ( Malik, Agarwal, Dhar và Frank, (HPCA-14: 50-61), 2008 ). Một công ty bán dẫn lớn nhất định bắt đầu sử dụng thuật ngữ siêu phân luồng cho đa luồng đồng thời, và cái tên đó dường như là tên được sử dụng rộng rãi nhất hiện nay.
Tôi nhận ra sau khi đọc lại bình luận của bạn rằng bạn cũng quan tâm đến tín hiệu diễn ra giữa bộ xử lý và bộ nhớ. Bộ nhớ cache hiện đại thường cho phép nhiều lần bỏ lỡ xuất hiện đồng thời. Đây được gọi là bộ đệm không khóa (Kroft, (ISCA-8): 81-87, 1981). . ), đó là cái tên Kroft đã đặt nó trong bài viết năm 1981 của mình.)
Câu trả lời ngắn gọn là: không có gì, quầy hàng xử lý.
Không có nhiều khả năng. Chuyển sang một nhiệm vụ khác không thực sự là một lựa chọn vì hai lý do. Đó là một hoạt động đắt tiền và vì tác vụ hiện tại và tác vụ khác đang cạnh tranh để có không gian trong bộ đệm, nên việc chuyển sang tác vụ khác có thể yêu cầu quyền truy cập bộ nhớ chính và do đó có thể chuyển về tác vụ ban đầu. Hơn nữa, điều này sẽ phải liên quan đến hệ điều hành, vì vậy bộ xử lý sẽ phải kích hoạt một số dạng gián đoạn hoặc bẫy - thực tế bộ xử lý sẽ chuyển sang một số mã hạt nhân.
Trong khi bộ xử lý bị đình trệ, bộ hẹn giờ tiếp tục chạy, do đó có thể có ngắt bộ hẹn giờ hoặc có thể có một ngắt từ các thiết bị ngoại vi khác. Vì vậy, một chuyển đổi ngữ cảnh có nhiều khả năng xảy ra trong khi truy cập bộ nhớ chính hơn là trong khi truy cập bộ đệm, nhưng chỉ vì mất nhiều thời gian hơn.
Tuy nhiên, các máy tính hiện đại bao gồm nhiều kỹ thuật khác nhau để cố gắng giảm thời gian lãng phí trong bộ xử lý đang chờ bộ nhớ chính. Sự đình trệ đã xảy ra, nhưng chỉ khi nó không thể tránh được.
Một kỹ thuật là tìm nạp đầu cơ : bộ xử lý cố gắng đoán vị trí bộ nhớ nào sẽ được truy cập và tìm nạp nó vào bộ đệm trước thời hạn. Ví dụ: các vòng lặp trên một khối bộ nhớ là phổ biến, vì vậy nếu các dòng bộ đệm đã được tải cho các địa chỉ bộ nhớ 0x12340000, 0x12340010 và 0x12340020, có thể nên tải dòng cho 0x12340030. Trình biên dịch có thể trợ giúp bằng cách tạo các lệnh tìm nạp trước giống như tải ngoại trừ việc chúng chỉ truyền dữ liệu từ bộ nhớ chính vào bộ đệm, chứ không phải vào một thanh ghi bộ xử lý.
Một kỹ thuật khác là thực hiện đầu cơ . Bộ xử lý bắt đầu thực hiện lệnh tiếp theo trước khi tải được thực hiện. Điều này xảy ra một cách tự nhiên mà thôi vì của pipelining của hướng dẫn. Chỉ các hướng dẫn không phụ thuộc vào giá trị được tải mới có thể được thực thi theo cách này: bộ xử lý phải thực hiện phân tích phụ thuộc. Đối với các hướng dẫn có điều kiện (ví dụ tải r1; nhánh nếu r1 0), bộ xử lý sử dụng phương pháp phỏng đoán dự đoán nhánh để đoán giá trị sẽ là gì. Thực hiện đầu cơ sau khi tải có thể cần phải được tua lại trong trường hợp tải kích hoạt hủy bỏ.
Một số kiến trúc như Itanium tạo điều kiện cho việc thực hiện các lệnh theo thứ tự thuận tiện bằng cách cho phép sắp xếp lại lệnh theo mặc định: thay vì bao gồm một chuỗi các lệnh cơ bản được thực hiện theo ngữ nghĩa lần lượt, các chương trình bao gồm các từ lệnh rất dài : một lệnh bao gồm nhiều hoạt động được thực hiện song song bởi các thành phần khác nhau của bộ xử lý.
Chuyển sang một luồng khác xảy ra trong siêu phân luồng , được tìm thấy trên các bộ xử lý x86 cao cấp. Đây là một kỹ thuật thiết kế phần cứng: mỗi lõi bộ xử lý chứa hai ngân hàng đăng ký riêng biệt (mỗi ngân hàng tương ứng với một bối cảnh nhiệm vụ), nhưng một trường hợp duy nhất của các yếu tố khác, để nó có thể hỗ trợ hai luồng thực thi độc lập, nhưng chỉ thực hiện hiệu quả các lệnh từ một tại một thời gian. Trong khi một chủ đề bị đình trệ, chủ đề khác tiến hành. Từ quan điểm của phần mềm, có hai bộ xử lý độc lập; nó chỉ xảy ra rằng những bộ xử lý chia sẻ nhiều thành phần dưới mui xe.
Hoán đổi là một cấp độ nữa trong hệ thống phân cấp bộ nhớ cache của bộ nhớ: bộ nhớ chính có thể được xem là bộ đệm cho không gian trao đổi. Với việc hoán đổi, các cơ chế và tỷ lệ hiệu suất là khác nhau. Nếu một tác vụ cần dữ liệu được tải từ trao đổi, lệnh tải sẽ kích hoạt một bẫy thực thi mã hạt nhân để phân bổ một trang trong RAM và tải nội dung của nó từ đĩa. Trong khi điều này xảy ra, kernel cũng có thể quyết định chuyển sang một nhiệm vụ khác.
Câu trả lời cho câu hỏi này sẽ thay đổi theo kiến trúc trong câu hỏi. Mặc dù nhiều CPU sẽ bị đình trệ (ARM, x86 w / o siêu phân luồng, v.v.) bởi vì chúng mất quá nhiều thời gian để chuyển đổi các luồng, đó không phải là cách tiếp cận của mọi kiến trúc. Trong một số kiến trúc, mỗi luồng được lên lịch trên CPU có tệp đăng ký độc lập của riêng nó, vì vậy bộ xử lý có thể chỉ cần thực hiện công việc từ một luồng không chờ trong truy cập bộ nhớ. Theo hiểu biết của tôi, điều này ở một mức độ hạn chế, siêu phân luồng x86 làm gì (chỉ sử dụng 2 luồng), nhưng nó phổ biến hơn nhiều trên GPGPUKiến trúc. Trong trường hợp cụ thể của CUDA, ít nhất hàng chục, nếu không phải hàng trăm sợi dọc của các luồng thường được tải trên một bộ xử lý nhất định tại bất kỳ thời điểm nào, với mỗi luồng (hàng trăm hoặc hàng nghìn) có các thanh ghi riêng. Điều này cho phép kiến trúc thực hiện một lệnh từ một luồng khác trong chu kỳ tiếp theo khi một luồng đã cho đưa ra quyền truy cập bộ nhớ. Vì vậy, miễn là đủ nhiều luồng được tải, lõi xử lý không bao giờ nhàn rỗi cho truy cập bộ nhớ. Xem Nguyên tắc hiệu suất và phân cấp bộ nhớ để biết thêm thông tin.