2012-06-30 33 views
6

Tôi đang viết một chương trình C mà tôi cần xóa bộ nhớ của mình. Tôi muốn biết nếu có bất kỳ lệnh hệ thống UNIX để tuôn ra bộ nhớ cache CPU.Làm thế nào để tuôn ra bộ nhớ cache CPU trong Linux từ một chương trình C?

Đây là yêu cầu đối với dự án của tôi liên quan đến việc tính toán thời gian thực hiện cho logic của tôi.

Tôi đã đọc về chức năng cacheflush(char *s, int a, int b) nhưng tôi không chắc chắn liệu nó có phù hợp hay không và những gì cần truyền vào các tham số.

+3

Tại sao bạn * nhu * để tuôn ra bộ nhớ cache? –

+0

nó là một yêu cầu cho dự án của tôi liên quan đến tính toán thời gian thực hiện cho logic của tôi, do đó tôi cần phải xóa bộ nhớ cache. –

+0

Có thể trùng lặp của http://stackoverflow.com/questions/1756825/cpu-cache-flush – Tudor

Trả lời

6
  1. Tôi mang nó bạn có nghĩa là "CPU bộ nhớ cache", không phải bộ nhớ cache

  2. Liên kết ở trên là tốt: gợi ý "viết rất nhiều dữ liệu thông qua CPU" là không Windows cụ thể

  3. đây là một biến thể của cùng một chủ đề:

  4. Dưới đây là một bài viết về Linux và bộ nhớ cache CPU:

LƯU Ý:

Tại này mức độ (rất, rất thấp), "Linux" ! = "Unix"

+0

Cảm ơn bạn đã giúp ích. Nó thực sự là một cộng đồng tốt với những người hữu ích ... bạn có thể vui lòng giải thích làm thế nào tôi nên sử dụng 'echo 3>/proc/sys/vm/drop_caches' trong chương trình C của tôi với một mã ví dụ nhỏ. –

+0

Một trong những phần đẹp của * nix (Unix nói chung và Linux cụ thể) là bạn có thể xử lý "mọi thứ như một tệp". Cụ thể: 'fopen ("/proc/sys/vm/drop_caches "," w "); fprintf (fp, "3"); fclose (fp); '. PS: Nếu điều này * là * bài tập về nhà, vui lòng sử dụng thẻ "bài tập về nhà" trong câu hỏi của bạn. – paulsm4

+0

Tôi đang sử dụng fopen ("proc/sys/vm.drop_caches", "w") .... nhưng làm cách nào để xác minh rằng bộ nhớ cache của tôi đã thực sự bị xóa. @ paulsm4 Cảm ơn bạn đã tốt bụng và giúp đỡ sớm hơn. Hy vọng bạn cũng sẽ giúp lần này. :) –

2

Nếu bạn đang viết chế độ người dùng (không phải là chế độ hạt nhân), và nếu nó là đơn luồng, sau đó thực sự không có lý do cho bạn bao giờ bận tâm đỏ bừng bộ nhớ cache của bạn ở nơi đầu tiên. Chương trình chế độ người dùng của bạn có thể quên rằng nó thậm chí còn tồn tại; nó chỉ có để tăng tốc độ thực thi chương trình của bạn, và hệ điều hành quản lý nó thông qua MMU của bộ vi xử lý.

Chỉ có một vài lý do tôi có thể nghĩ rằng bạn thực sự có thể muốn tuôn bộ nhớ cache từ các ứng dụng sử dụng chế độ của bạn:

  1. ứng dụng của bạn được thiết kế để chạy trên một hệ thống đa xử lý đối xứng, hoặc có giao dịch dữ liệu với phần cứng bên ngoài)
  2. Bạn chỉ cần kiểm tra bộ nhớ cache của mình để kiểm tra hiệu suất (trong trường hợp này bạn nên viết test để hoạt động ở chế độ hạt nhân, có thể là trình điều khiển).

Trong mọi trường hợp, giả sử bạn đang sử dụng Linux ...

#include <asm/cachectl.h> 

int cacheflush(char *addr, int nbytes, int cache); 

này giả định bạn có một khối bộ nhớ bạn chỉ cần viết cho và bạn muốn chắc chắn nó đỏ ửng ra khỏi bộ nhớ cache trở lại bộ nhớ chính. Khối bắt đầu tại addr, và nó nbytes dài, và đó là một trong hai bộ nhớ đệm (hoặc cả hai):

ICACHE Flush the instruction cache. 
    DCACHE Write back to memory and invalidate the affected valid cache lines. 
    BCACHE Same as (ICACHE|DCACHE). 

Thông thường bạn muốn chỉ cần để tuôn ra DCACHE, kể từ khi bạn ghi dữ liệu vào "bộ nhớ "(tức là vào bộ nhớ cache), nó thường là dữ liệu chứ không phải hướng dẫn.

Nếu bạn muốn xóa "tất cả bộ nhớ cache" vì một số lý do thử nghiệm lạ, bạn có thể malloc() một khối lớn mà bạn biết lớn hơn bộ nhớ cache của CPU (quay, làm to gấp 8 lần!), viết bất kỳ rác cũ vào nó, và chỉ tuôn ra toàn bộ khối đó.

Xem thêm: How to perform cache operations in C++?

+0

Cảm ơn bạn đã rất hữu ích. Làm thế nào tôi có thể biết kích thước của bộ nhớ cache CPU của tôi trong ubuntu/unix/linux .. tôi muốn xóa toàn bộ bộ nhớ cache –

+0

Xem http://superuser.com/questions/48505/how-to-find-virtual-memory -size-and-cache-size-of-a-linux-system Xem thêm câu trả lời thứ hai của tôi mà tôi nghĩ có lẽ là nhiều hơn dọc theo dòng của những gì bạn đang tìm kiếm ... Tôi muốn nói "nhiều hơn dọc theo dòng những gì bạn cần "ngoại trừ tôi nghĩ rằng mục tiêu của bạn xả bộ nhớ cache cho thử nghiệm hiệu suất là sai lầm. Những gì tôi nghĩ sẽ có ý nghĩa hơn đối với việc kiểm tra hiệu năng sẽ là kiểm tra hiệu suất của mã của bạn SAU KHI nó được tải vào bộ nhớ cache, bằng cách chạy nó một lần để lấy nó vào bộ đệm, sau đó sử dụng bộ đếm thời gian để kiểm tra nó có thể gấp 10.000 lần và chia thời gian 10.000. – phonetagger

+0

'lỗi: asm/cachectl.h: Không có tệp hoặc thư mục nào' trình biên dịch gnu-gcc trên linux ném lỗi này. Bất kỳ ý tưởng làm thế nào để giải quyết nó ... như vậy mà nó chấp nhận cachectl.h như là một tập tin tiêu đề. –

1

OK, xin lỗi về câu trả lời đầu tiên của tôi. Sau đó, tôi nhận ra các ý kiến ​​tiếp theo của bạn bên dưới câu hỏi của bạn, vì vậy tôi nhận ra rằng bạn muốn tuôn ra HƯỚNG DẪN CÀI ĐẶT để khởi động chương trình (hoặc một phần của nó) ra khỏi bộ đệm, để khi bạn kiểm tra hiệu năng của nó, bạn cũng kiểm tra thời gian tải ban đầu của nó ra khỏi bộ nhớ chính vào bộ nhớ cache lệnh. Bạn cũng cần xóa bất kỳ dữ liệu nào mà mã của bạn sẽ sử dụng cho bộ nhớ chính, sao cho cả dữ liệu và mã đều là tải mới?

Trước khi bất cứ điều gì khác, tôi muốn đề cập đến chính bộ nhớ chính cũng là một hình thức bộ nhớ cache, với đĩa cứng của bạn (hoặc chương trình trên đĩa, hoặc không gian trao đổi trên đĩa). hướng dẫn có thể đến từ. Điều đó nói rằng, khi lần đầu tiên bạn chạy qua một thường trình lần đầu tiên, nếu nó chưa được nạp vào bộ nhớ chính từ đĩa nhờ vào gần mã khác đã thực thi, thì các hướng dẫn CPU của nó trước tiên sẽ được nạp từ đĩa. Điều đó có một thứ tự độ lớn hoặc dài hơn tải nó từ bộ nhớ chính vào bộ nhớ cache. Sau đó, khi nó được nạp vào bộ nhớ chính, phải mất một nơi nào đó dọc theo các dòng của một trật tự cường độ dài hơn để tải từ bộ nhớ chính vào bộ nhớ cache hơn cần để tải từ bộ nhớ cache vào trình tìm nạp lệnh của CPU. Vì vậy, nếu bạn muốn kiểm tra hiệu suất khởi động nguội của mã, bạn phải quyết định khởi động nguội nghĩa là gì .... kéo nó ra khỏi đĩa, hoặc kéo nó ra khỏi bộ nhớ chính. Tôi không biết bất kỳ lệnh nào để "tuôn ra" hướng dẫn/dữ liệu ra khỏi bộ nhớ chính để trao đổi không gian, do đó xả nó ra bộ nhớ chính là nhiều như bạn có thể làm (mà tôi biết), nhưng hãy nhớ kết quả kiểm tra của bạn có thể vẫn khác với lần chạy đầu tiên (khi nó có thể kéo nó ra khỏi ổ đĩa) cho các lần chạy tiếp theo, ngay cả khi bạn xóa bộ nhớ cache lệnh.

Bây giờ, làm thế nào một trong những đi về xả bộ nhớ cache hướng dẫn để đảm bảo rằng mã riêng của họ được flushed ra bộ nhớ chính?

Nếu tôi cần làm điều này (điều rất kỳ lạ để làm theo ý kiến ​​của tôi), tôi có thể bắt đầu bằng cách tìm độ dài & vị trí gần đúng của các chức năng của tôi trong bộ nhớ. Vì tôi đang sử dụng Linux, tôi sẽ đưa ra lệnh "objdump -d {myprogram}> myprogram.dump.txt", sau đó tôi mở myprogram.dump.txt trong trình chỉnh sửa và tìm kiếm các hàm tôi muốn xóa ra, và tìm ra bao lâu họ bằng cách trừ địa chỉ kết thúc của họ tạo thành địa chỉ bắt đầu của họ bằng cách sử dụng một máy tính hex. Tôi viết ra các kích thước của mỗi cái. Sau đó, tôi sẽ thêm các lời gọi cacheflush() vào mã của tôi, cho nó địa chỉ của mỗi hàm mà tôi muốn xóa như 'addr' và độ dài mà tôi tìm thấy là 'nbytes' và ICACHE. Chỉ cần cho an toàn tôi có lẽ sẽ fudge một chút & thêm khoảng 10% kích thước, chỉ trong trường hợp tôi thực hiện một vài tinh chỉnh cho mã và quên điều chỉnh nbyte. Tôi muốn thực hiện một cuộc gọi đến cacheflush() như thế này cho mỗi chức năng tôi muốn tuôn ra. Sau đó, nếu tôi cần xóa dữ liệu, nếu nó sử dụng dữ liệu toàn cục/tĩnh, tôi cũng có thể xóa các dữ liệu đó (DCACHE), nhưng nếu đó là dữ liệu đống hoặc đống, thực sự không có gì thực tế mà tôi có thể làm ra khỏi bộ nhớ cache. Cố gắng làm như vậy sẽ là một bài tập trong bấp bênh, bởi vì nó sẽ tạo ra một điều kiện không bao giờ hoặc rất hiếm khi tồn tại trong thực thi bình thường. Giả sử bạn đang sử dụng Linux ...

#include <asm/cachectl.h> 

int cacheflush(char *addr, int nbytes, int cache); 

...where cache is one of: 
    ICACHE Flush the instruction cache. 
    DCACHE Write back to memory and invalidate the affected valid cache lines. 
    BCACHE Same as (ICACHE|DCACHE). 

BTW, đây có phải là bài tập về nhà cho lớp học không?

+0

Hỏi: Điều này chỉ áp dụng ở chế độ hạt nhân, đúng không? – paulsm4

+0

@ paulsm4 - Trang người đàn ông Linux không nói gì về điều đó. Hừm. Đọc trên trang người đàn ông ... (Tôi giả sử bạn đang sử dụng Linux, phải không? Nếu vậy, bạn đã thử lệnh "man cacheflush"?) ... gần phía dưới, tôi thấy hai điều trong phiên bản của tôi của trang người đàn ông đó là nguyên nhân gây lo ngại .... "LGSI - Việc triển khai hiện tại bỏ qua các đối số addr và nbytes. Do đó, toàn bộ bộ nhớ cache luôn bị xóa." Và tiếp tục ... "LƯU Ý - Cuộc gọi hệ thống này chỉ có sẵn trên các hệ thống dựa trên MIPS. Nó không nên được sử dụng trong các chương trình có ý định di động." – phonetagger

+1

@ paulsm4 lỗi: asm/cachectl.h: Không có tệp hoặc thư mục nào như trình biên dịch gnu-gcc trên linux ném lỗi này. Bất kỳ ý tưởng làm thế nào để giải quyết nó ... như vậy mà nó chấp nhận cachectl.h như là một tập tin tiêu đề. –

1

Đây là cách Intel cho thấy đỏ bừng cache:

mem_flush(const void *p, unsigned int allocation_size){ 
    const size_t cache_line = 64; 
    const char *cp = (const char *)p; 
    size_t i = 0; 

    if (p == NULL || allocation_size <= 0) 
      return; 

    for (i = 0; i < allocation_size; i += cache_line) { 
      asm volatile("clflush (%0)\n\t" 
         : 
         : "r"(&cp[i]) 
         : "memory"); 
    } 

    asm volatile("sfence\n\t" 
       : 
       : 
       : "memory"); 
} 
+0

nguồn của bạn là gì? – horro

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