Ý nghĩa của việc truy cập bộ nhớ “phi thời gian” trong x86 là gì


123

Đây là một câu hỏi hơi thấp. Trong x86 assembly, có hai lệnh SSE:

MOVDQA xmmi, m128

MOVNTDQA xmmi, m128

Sổ tay hướng dẫn của Nhà phát triển Phần mềm IA-32 nói rằng NT trong MOVNTDQA là viết tắt của Non-Temporal , và nếu không thì nó giống với MOVDQA.

Câu hỏi của tôi là, Phi thời gian nghĩa là gì?


6
Lưu ý rằng SSE4.1 MOVNTDQA xmmi, m128là tải NT, trong khi tất cả các hướng dẫn NT khác đều là cửa hàng, ngoại trừ prefetchnta. Câu trả lời được chấp nhận ở đây dường như chỉ nói về các cửa hàng. Đây là những gì tôi có thể bật mí về tải NT . TL: DR: hy vọng CPU làm điều gì đó hữu ích với gợi ý NT để giảm thiểu ô nhiễm bộ nhớ cache, nhưng chúng không ghi đè ngữ nghĩa được sắp xếp chặt chẽ của bộ nhớ WB "bình thường", vì vậy chúng phải sử dụng bộ nhớ cache.
Peter Cordes

5
Cập nhật: Tải NT có thể không làm bất cứ điều gì hữu ích ngoại trừ trên các vùng bộ nhớ UCSW trên hầu hết các CPU (ví dụ: dòng Intel SnB). Tuy nhiên, các cửa hàng NT / streaming chắc chắn hoạt động trên bộ nhớ bình thường.
Peter Cordes

4
@Peter: Ý bạn là bộ nhớ USWC phải không? Tôi chưa bao giờ nghe nói về bộ nhớ UCSW hoặc USWC trước đây. Googling viết tắt sai là không hữu ích :-)
Andrew Bainbridge

4
@AndrewBainbridge: Có, thuộc tính loại bộ nhớ WC. Kết hợp ghi đầu cơ không thể lưu trữ. Tôi nghĩ rằng tôi đã viết hoa UnCacheable và nhớ rằng nó phải dài 4 chữ cái. : P
Peter Cordes

Câu trả lời:


147

Hướng dẫn SSE không theo thời gian (MOVNTI, MOVNTQ, v.v.), không tuân theo quy tắc đồng tiền mã hóa bộ đệm thông thường. Do đó, các cửa hàng phi thời gian phải được tuân theo chỉ dẫn SFENCE để các bộ xử lý khác có thể nhìn thấy kết quả của họ một cách kịp thời.

Khi dữ liệu được tạo ra và không (ngay lập tức) được tiêu thụ trở lại, thực tế là các hoạt động lưu trữ bộ nhớ đọc toàn bộ dòng bộ nhớ cache trước và sau đó sửa đổi dữ liệu đã lưu trong bộ nhớ cache sẽ gây bất lợi cho hiệu suất. Thao tác này đẩy dữ liệu ra khỏi bộ nhớ đệm, dữ liệu có thể cần thiết lại có lợi cho dữ liệu sẽ sớm không được sử dụng. Điều này đặc biệt đúng đối với các cấu trúc dữ liệu lớn, như ma trận, được lấp đầy và sử dụng sau đó. Trước khi phần tử cuối cùng của ma trận được lấp đầy, kích thước tuyệt đối sẽ loại bỏ các phần tử đầu tiên, khiến việc ghi vào bộ nhớ đệm không hiệu quả.

Đối với trường hợp này và các tình huống tương tự, bộ xử lý cung cấp hỗ trợ cho các hoạt động ghi phi thời gian. Phi thời gian trong ngữ cảnh này có nghĩa là dữ liệu sẽ không sớm được sử dụng lại, vì vậy không có lý do gì để lưu vào bộ nhớ cache. Các hoạt động ghi phi thời gian này không đọc một dòng trong bộ nhớ cache và sau đó sửa đổi nó; thay vào đó, nội dung mới được ghi trực tiếp vào bộ nhớ.

Nguồn: http://lwn.net/Articles/255364/


15
Câu trả lời rất hay, tôi chỉ muốn chỉ ra rằng trên loại bộ xử lý có lệnh NT, ngay cả với lệnh phi thời gian (tức là lệnh bình thường), bộ đệm dòng không được "đọc và sau đó sửa đổi". Đối với một lệnh bình thường ghi vào một dòng không có trong bộ đệm, một dòng được dành riêng trong bộ đệm và một mặt nạ cho biết những phần nào của dòng được cập nhật. Trang web này gọi nó là "không có gian hàng tại cửa hàng": ptlsim.org/Documentation/html/node30.html . Tôi không thể tìm thấy tài liệu tham khảo chính xác hơn, tôi chỉ nghe nói về điều này từ những người có công việc là triển khai trình mô phỏng bộ xử lý.
Pascal Cuoq

2
Trên thực tế ptlsim.org là một trang web về trình mô phỏng bộ xử lý chính xác theo chu kỳ, giống hệt như điều mà những người đã nói với tôi về "không có gian hàng trên cửa hàng" đang làm. Tốt hơn hết tôi nên đề cập đến họ trong trường hợp họ nhìn thấy nhận xét này: unisim.org
Pascal Cuoq

1
Từ các câu trả lời và nhận xét ở đây stackoverflow.com/questions/44864033/…SFENCEthể không cần. Ít nhất là trong cùng một chủ đề. Bạn cũng có thể nhìn?
Serge Rogatch

1
@SergeRogatch nó phụ thuộc vào kịch bản bạn đang nói đến, nhưng có, có những tình huống sfencebắt buộc đối với các cửa hàng NT, trong khi nó không bao giờ bắt buộc đối với các cửa hàng bình thường. Cửa hàng NT không được đặt hàng đối với các cửa hàng khác (NT hoặc không), như các chủ đề khác đã thấy , không có sfence. Tuy nhiên, đối với các lần đọc từ cùng một chuỗi đã lưu trữ, bạn không bao giờ cần sfence: một chuỗi nhất định sẽ luôn nhìn thấy các cửa hàng của chính nó theo thứ tự chương trình, bất kể chúng có phải là cửa hàng NT hay không.
BeeOnRope

40

Espo khá nhiều vào mục tiêu. Tôi chỉ muốn thêm hai xu của tôi:

Cụm từ "phi thời" có nghĩa là thiếu tính cục bộ theo thời gian. Bộ nhớ đệm khai thác hai loại địa phương - không gian và thời gian và bằng cách sử dụng lệnh phi thời gian, bạn đang báo hiệu cho bộ xử lý rằng bạn không mong đợi mục dữ liệu sẽ được sử dụng trong tương lai gần.

Tôi hơi nghi ngờ về tổ hợp mã hóa thủ công sử dụng các hướng dẫn điều khiển bộ nhớ cache. Theo kinh nghiệm của tôi, những điều này dẫn đến nhiều lỗi xấu hơn bất kỳ sự gia tăng hiệu suất hiệu quả nào.


câu hỏi về "lắp ráp mã hóa thủ công sử dụng hướng dẫn điều khiển bộ đệm." Tôi biết bạn đã nói rõ ràng là "viết mã bằng tay" thì sao về một thứ như JavaVM. Đây có phải là một trường hợp sử dụng tốt hơn? JavaVM / Compiler đã phân tích hành vi tĩnh và động của chương trình và sử dụng các hướng dẫn phi thời gian này.
Pat

4
Không nên bỏ qua việc khai thác các thuộc tính cục bộ đã biết (hoặc thiếu) của miền, thuật toán hoặc ứng dụng có vấn đề. Tránh ô nhiễm bộ nhớ cache thực sự là một nhiệm vụ tối ưu hóa rất hấp dẫn và hiệu quả. Ngoài ra, tại sao ác cảm đối với lắp ráp? Có một lượng lớn các cơ hội cho lợi nhuận sẵn mà một trình biên dịch không thể nào tận dụng
awdz9nld

5
Điều chắc chắn đúng là một lập trình viên cấp thấp có kiến ​​thức có thể làm tốt hơn một trình biên dịch cho các hạt nhân nhỏ. Điều này rất tốt cho việc xuất bản các bài báo và bài đăng blog và tôi đã làm cả hai. Chúng cũng là công cụ giáo khoa tốt và giúp hiểu những gì "thực sự" đang diễn ra. Tuy nhiên, theo kinh nghiệm của tôi, trong thực tế, nơi bạn có một hệ thống thực với nhiều lập trình viên làm việc trên đó và tính đúng đắn và khả năng bảo trì là rất quan trọng, thì lợi ích của việc mã hóa cấp thấp hầu như luôn luôn lớn hơn rủi ro.
Pramod

4
@Pramod cùng lập luận đó dễ dàng tổng quát thành tối ưu hóa nói chung và không thực sự nằm trong phạm vi thảo luận - rõ ràng rằng sự đánh đổi đã được cân nhắc hoặc được cho là không liên quan do thực tế là chúng ta đã nói về các hướng dẫn phi thời gian
awdz9nld

7

Theo Sổ tay dành cho nhà phát triển phần mềm kiến ​​trúc Intel® 64 và IA-32, Tập 1: Kiến trúc cơ bản, chương "Lập trình với Tiện ích mở rộng SIMD của Intel Streaming (Intel SSE)":

Lưu trữ dữ liệu tạm thời so với dữ liệu phi thời gian

Dữ liệu được tham chiếu bởi một chương trình có thể là tạm thời (dữ liệu sẽ được sử dụng lại) hoặc phi thời gian (dữ liệu sẽ được tham chiếu một lần và không được sử dụng lại trong tương lai). Ví dụ, mã chương trình thường mang tính thời gian, trong khi dữ liệu đa phương tiện, chẳng hạn như danh sách hiển thị trong ứng dụng đồ họa 3-D, thường không mang tính thời gian. Để sử dụng hiệu quả bộ nhớ đệm của bộ xử lý, thông thường bạn nên lưu vào bộ đệm dữ liệu tạm thời chứ không phải bộ đệm dữ liệu phi thời gian. Việc nạp quá nhiều bộ nhớ đệm của bộ xử lý với dữ liệu phi thời gian đôi khi được gọi là "làm ô nhiễm bộ nhớ đệm". Hướng dẫn kiểm soát khả năng lưu trong bộ nhớ cache của SSE và SSE2 cho phép chương trình ghi dữ liệu phi thời gian vào bộ nhớ theo cách giảm thiểu ô nhiễm bộ nhớ đệm.

Mô tả tải trọng phi thời gian và hướng dẫn lưu trữ. Nguồn: Sách hướng dẫn của nhà phát triển phần mềm kiến ​​trúc Intel 64 và IA-32, Tập 2: Tham khảo bộ hướng dẫn

TẢI (MOVNTDQA — Tải Gợi ý được căn chỉnh từ bốn chữ cái kép không theo thời gian)

Tải một từ kép từ toán hạng nguồn (toán hạng thứ hai) đến toán hạng đích (toán hạng thứ nhất) bằng cách sử dụng gợi ý phi thời gian nếu nguồn bộ nhớ là loại bộ nhớ WC (kết hợp ghi) [...]

[...] bộ xử lý không đọc dữ liệu vào phân cấp bộ đệm, cũng như không tìm nạp dòng bộ đệm tương ứng từ bộ nhớ vào phân cấp bộ đệm.

Lưu ý rằng, như Peter Cordes nhận xét, nó không hữu ích trên bộ nhớ WB bình thường (ghi lại) trên bộ xử lý hiện tại vì gợi ý NT bị bỏ qua (có thể vì không có bộ nạp trước HW nhận biết NT) và áp dụng ngữ nghĩa tải được sắp xếp mạnh mẽ đầy đủ . prefetchntacó thể được sử dụng như một tải giảm ô nhiễm từ bộ nhớ WB

CỬA HÀNG (MOVNTDQ — Lưu trữ số nguyên được đóng gói bằng cách sử dụng gợi ý phi thời gian)

Di chuyển các số nguyên được đóng gói trong toán hạng nguồn (toán hạng thứ hai) đến toán hạng đích (toán hạng thứ nhất) bằng cách sử dụng gợi ý phi thời gian để ngăn chặn dữ liệu được lưu vào bộ nhớ đệm trong quá trình ghi vào bộ nhớ.

[...] bộ xử lý không ghi dữ liệu vào phân cấp bộ đệm, cũng như không tìm nạp dòng bộ đệm tương ứng từ bộ nhớ vào phân cấp bộ đệm.

Sử dụng thuật ngữ được định nghĩa trong Chính sách và Hiệu suất Ghi vào Bộ nhớ cache , chúng có thể được coi là ghi xung quanh (không ghi-phân bổ, không tìm nạp-khi ghi-bỏ lỡ).

Cuối cùng, có thể thú vị khi xem lại các ghi chú của John McAlpin về các cửa hàng phi thời gian .


3
SSE4.1 MOVNTDQAchỉ thực hiện bất cứ điều gì đặc biệt trên các vùng bộ nhớ WC (không thể lưu vào bộ nhớ cache), ví dụ: RAM video. Nó hoàn toàn không hữu ích trên bộ nhớ WB (ghi lại) bình thường trên HW hiện tại, gợi ý NT bị bỏ qua và áp dụng ngữ nghĩa tải có thứ tự mạnh mẽ đầy đủ. prefetchntacó thể hữu ích, mặc dù, như một tải giảm ô nhiễm từ bộ nhớ WB. Các kiến ​​trúc x86 hiện tại có hỗ trợ tải phi thời gian (từ bộ nhớ "bình thường") không? .
Peter Cordes

2
Đúng vậy, bộ lưu trữ NT hoạt động tốt trên bộ nhớ WB, và được sắp xếp yếu, và thường là lựa chọn tốt để ghi các vùng bộ nhớ lớn. Nhưng tải NT thì không. Hướng dẫn sử dụng x86 trên giấy cho phép gợi ý NT làm điều gì đó để tải từ bộ nhớ WB, nhưng trong các CPU hiện tại, nó không làm gì cả . (Có thể là do không có trình cài đặt trước HW nhận biết được NT.)
Peter Cordes

Tôi đã thêm thông tin liên quan đó vào câu trả lời. Cảm ơn rât nhiều.
chus

1
@LewisKelsey: Các cửa hàng NT ghi đè loại bộ nhớ. Đó là lý do tại sao chúng có thể được sắp xếp một cách yếu ớt trên bộ nhớ WB. Hiệu quả chính là tránh được các RFO (rõ ràng là chúng gửi một lệnh vô hiệu thậm chí xóa các dòng bẩn khác khi chúng đến được mem). Chúng cũng có thể trở nên không theo thứ tự hiển thị, vì vậy chúng không phải đợi cho đến sau lần cam kết lưu trữ bộ nhớ cache (thông thường) trước đó hoặc cho đến khi tải bộ nhớ cache trước đó lấy dữ liệu. tức là loại nút cổ chai được hỏi trong Bộ nhớ bên ngoài mỗi lõi có luôn luôn về khái niệm phẳng / đồng nhất / đồng bộ trong một hệ thống đa xử lý không? .
Peter Cordes

1
@LewisKelsey: Một máy xóa sắp xếp bộ nhớ có thể giết chết bất kỳ tải nào từ sau một cửa hàng UC mà lẽ ra không nên thực hiện sớm, nếu cần. Ngoài ra, lệnh cam kết sẽ không có hiệu lực cho đến khi cửa hàng ngừng giao hàng hết hàng. Điều đó không thể xảy ra cho đến sau khi uop địa chỉ cửa hàng được thực thi, lúc này loại bộ nhớ cho địa chỉ có thể được kiểm tra. Uop địa chỉ cửa hàng kiểm tra TLB khi nó thực thi; đó là cách CPU có thể phát hiện các cửa hàng lỗi trước khi chúng nghỉ hưu. Không thể đợi cho đến khi mục SB sẵn sàng cam kết với L1d; tại thời điểm đó việc thực thi đã qua nó.
Peter Cordes
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.