2009-08-12 28 views
15

Tôi muốn đọc một vị trí bộ nhớ mà không gây ô nhiễm bộ nhớ cache. Tôi đang làm việc trên máy X86 Linux. Tôi đã thử sử dụng hướng dẫn lắp ráp MOVNTDQA:Làm cách nào để tải các giá trị từ bộ nhớ mà không làm ô nhiễm bộ đệm ẩn?

asm("movntdqa %[source], %[dest] \n\t" 
     : [dest] "=x" (my_var) : [source] "m" (my_mem[0]) : "memory"); 

my_mem là một int * được phân bổ với new, my_var là một int.

Tôi có hai vấn đề với cách tiếp cận này:

  1. mã biên dịch nhưng tôi nhận được "Chỉ thị bất hợp pháp" báo lỗi khi chạy nó. Bất kỳ ý tưởng tại sao?
  2. Tôi không chắc chắn loại bộ nhớ nào được cấp phát mới. Tôi cho rằng WB. Theo tài liệu, lệnh MOVNTDQA sẽ chỉ hoạt động với loại bộ nhớ USWC. Làm thế nào tôi có thể biết tôi đang làm việc với loại bộ nhớ nào?

Để tóm tắt, câu hỏi của tôi là:

Làm thế nào tôi có thể đọc một vị trí bộ nhớ mà không làm ô nhiễm bộ nhớ cache trên một máy X86? Cách tiếp cận của tôi có đúng hướng không và nó có thể được cố định để làm việc không?

Cảm ơn.

+0

Câu hỏi này có liên quan không? http: // stackoverflow.com/questions/851286/how-to-use-movntdqa-to-avoid-cache-ô nhiễm – sharptooth

+1

Tôi đoán nó liên quan :), nhưng không may, câu hỏi/câu trả lời đó không giúp tôi với câu hỏi này. – Anna

+0

Ồ, một điều nữa: Tôi không chắc chắn rằng nó thậm chí có thể làm điều này: -/Tôi chắc chắn hy vọng nó được. – Anna

Trả lời

0

MOVNTDQA chỉ khả dụng với SSE.

Tại sao bạn đang cố tránh sử dụng bộ nhớ cache? CPU nói chung là khá tốt trong việc quyết định những gì để kick ra khỏi bộ nhớ cache khi nào. Nếu thực sự cần phải, một cách sẽ được sắp xếp cho một bí danh của khu vực bộ nhớ bạn đang đọc từ được ánh xạ vào không gian địa chỉ của bạn với bộ nhớ đệm bị vô hiệu hóa và đọc từ đó.

Nếu những gì bạn đang cố gắng đạt được là giảm thiểu tác động của mã trên bộ làm việc của một hàm khác đang được lưu trong bộ nhớ cache vào thời điểm đó, điều này có thể thực hiện được bằng cách phát hành các lệnh tìm nạp trước và vô hiệu hợp.

+0

Tôi có hai lõi trên một quy trình - một trong số đó là sử dụng bộ nhớ cache và một số khác có mức độ ưu tiên thấp hơn và do đó tôi đang cố gắng giảm mức sử dụng bộ nhớ cache của nó. Trên máy này, bộ nhớ cache L2 là lẫn nhau cho hai lõi - vì vậy những gì tôi muốn làm là cho bộ nhớ được nạp trực tiếp vào L1 hoặc tới thanh ghi (trong chương trình ưu tiên thấp hơn). Bạn có thể vui lòng giải thích cách sử dụng tìm nạp trước và hướng dẫn không hợp lệ có thể giúp tôi trong trường hợp này không? Rất cám ơn. – Anna

+0

Suy nghĩ của tôi là sắp xếp quy trình ưu tiên thấp để vạch rõ các dòng bộ nhớ cache ngay khi nó được thực hiện với chúng, do đó cho phép chúng được nạp lại sớm hơn chính sách quản lý bộ nhớ cache của CPU có thể cho phép, và có thể sắp xếp cho quy trình ưu tiên cao để phát hành các tìm nạp trước trong các phần đặc biệt tốn kém. Tuy nhiên, không chắc chắn cách tiếp cận này sẽ giúp ích cho kịch bản của bạn như thế nào. – moonshadow

+3

@moonshadow: Bộ vi xử lý không phải lúc nào cũng tốt để quyết định bộ nhớ cache. Đó là lý do rõ ràng tại sao có một lệnh movntdqa. Của nó cho streaming dữ liệu, một khi được sử dụng, không bao giờ chạm vào một lần nữa (ít nhất là không quá sớm ;-)). Đối với một chuỗi trợ giúp, điều này có thể là khả thi, nếu có một luồng khác có sẵn, mà không thể được sử dụng đầy đủ nếu không - siêu luồng đến tâm trí. Nhưng trong hầu hết các trường hợp, bạn sẽ nhận được kết quả tốt hơn với hai luồng làm việc đầy đủ và sử dụng các hướng dẫn tìm nạp trước rõ ràng. – hirschhornsalz

7

Vấn đề với lệnh movntdqa với %% xmm là đích (tải từ bộ nhớ) là insn này chỉ khả dụng với SSE4.1 và bật. Điều này có nghĩa là mới hơn Core 2 (45 nm) hoặc i7 chỉ cho đến nay. Cách khác xung quanh (lưu trữ dữ liệu vào bộ nhớ) có sẵn trong các phiên bản SSE trước đó.

Đối với hướng dẫn này, bộ xử lý di chuyển dữ liệu vào một rất ít bộ đệm được đọc rất ít (Intel không chỉ định kích thước chính xác, nhưng giả sử nó nằm trong phạm vi 16 byte), nơi sẵn có, nhưng bị đuổi ra sau một vài lần tải khác.

Và nó không gây ô nhiễm các bộ đệm khác, vì vậy nếu bạn có dữ liệu trực tuyến, cách tiếp cận của bạn là khả thi.

Hãy nhớ rằng, bạn cần phải sử dụng tính năng chèn thông tin sau đó.

Tìm nạp trước tồn tại trong hai biến thể: prefetcht0 (Tìm nạp trước dữ liệu trong tất cả bộ nhớ cache) và tìm nạp trước (Tìm nạp trước dữ liệu không phải thời gian). Thông thường, tìm nạp trước trong tất cả bộ nhớ cache là điều đúng đắn để làm, đối với vòng lặp dữ liệu luồng, sau này sẽ tốt hơn nếu bạn sử dụng kết quả các hướng dẫn truyền trực tuyến.

Bạn sử dụng nó với địa chỉ của đối tượng bạn muốn sử dụng trong tương lai gần, thường là một số lần lặp lại phía trước nếu bạn có vòng lặp. Hàm nạp trước không chờ hoặc chặn, nó chỉ làm cho bộ xử lý bắt đầu nhận dữ liệu tại vị trí bộ nhớ được chỉ định.

Các vấn đề liên quan