2015-07-16 16 views
5

Bắt đầu từ bài viết này - Gallery of Processor Cache Effects bởi Igor Ostrovsky - Tôi muốn chơi với các ví dụ của anh ấy trên máy của riêng tôi. Đây là mã của tôi cho ví dụ đầu tiên, mà nhìn vào dòng bộ nhớ cache cách cảm khác nhau ảnh hưởng đến thời gian chạy:Kiểm tra đơn giản để đo kích thước đường bộ nhớ cache

#include <iostream> 
#include <time.h> 

using namespace std; 

int main(int argc, char* argv[]) 
{ 
    int step = 1; 

    const int length = 64 * 1024 * 1024; 
    int* arr = new int[length]; 

    timespec t0, t1; 
    clock_gettime(CLOCK_REALTIME, &t0); 
    for (int i = 0; i < length; i += step) 
     arr[i] *= 3; 
    clock_gettime(CLOCK_REALTIME, &t1); 

    long int duration = (t1.tv_nsec - t0.tv_nsec); 
    if (duration < 0) 
     duration = 1000000000 + duration; 

    cout<< step << ", " << duration/1000 << endl; 

    return 0; 
} 

Sử dụng giá trị khác nhau cho bước, tôi không thấy sự nhảy vọt trong thời gian chạy:

step, microseconds 
1, 451725 
2, 334981 
3, 287679 
4, 261813 
5, 254265 
6, 246077 
16, 215035 
32, 207410 
64, 202526 
128, 197089 
256, 195154 

tôi sẽ mong đợi để xem một cái gì đó tương tự với:

Nhưng từ ngày 16 trở đi, thời gian chạy được một nửa mỗi lần chúng tôi tăng gấp đôi bước.

Tôi thử nghiệm trên Ubuntu13, Xeon X5450 và biên dịch bằng: g ++ -O0. Có điều gì đó thiếu sót với mã của tôi hay kết quả thực sự ổn không? Bất kỳ thông tin chi tiết nào về những gì tôi thiếu sẽ được đánh giá cao.

+2

Đo hiệu suất bằng '-O0' là một sự lãng phí thời gian. Đừng làm thế. Hãy thử '-O2' hoặc thậm chí' -march = native', đặc biệt. nếu chơi với bộ nhớ cache. – erenon

+0

@erenon - the -O0 là cần thiết để gán mảng không được tối ưu hóa. Kết quả không được sử dụng, vì vậy tính toán có thể bị xóa. –

+0

@ CraigS.Anderson: đó không phải là lý do để đo lường hiệu suất mà không cần tối ưu hóa. Sử dụng kết quả sau đó - nó đơn giản. – erenon

Trả lời

0

Khi tôi thấy bạn muốn quan sát hiệu ứng của kích thước đường bộ nhớ cache, tôi khuyên bạn nên sử dụng công cụ cachegrind, một phần của bộ công cụ valgrind. Cách tiếp cận của bạn là đúng nhưng không gần với kết quả.

#include <iostream> 
#include <time.h> 
#include <stdlib.h> 

using namespace std; 

int main(int argc, char* argv[]) 
{ 
    int step = atoi(argv[1]); 

    const int length = 64 * 1024 * 1024; 
    int* arr = new int[length]; 

    for (int i = 0; i < length; i += step) 
     arr[i] *= 3; 
    return 0; 
} 

Chạy công cụ valgrind --tool = cachegrind ./a.out $ cacheline kích thước và bạn sẽ thấy kết quả. Sau khi vẽ đồ thị này, bạn sẽ nhận được kết quả mong muốn với độ chính xác. Thử nghiệm hạnh phúc !!

0
public class CacheLine { 

public static void main(String[] args) { 
    CacheLine cacheLine = new CacheLine(); 
    cacheLine.startTesting(); 
} 

private void startTesting() { 
    byte[] array = new byte[128 * 1024]; 
    for (int testIndex = 0; testIndex < 10; testIndex++) { 
     testMethod(array); 
     System.out.println("--------- // ---------"); 
    } 

} 

private void testMethod(byte[] array) { 
    for (int len = 8192; len <= array.length; len += 8192) { 

     long t0 = System.nanoTime(); 
     for (int i = 0; i < 10000; i++) { 
      for (int k = 0; k < len; k += 64) { 
       array[k] = 1; 
      } 
     } 

     long dT = System.nanoTime() - t0; 
     System.out.println("len: " + len/1024 + " dT: " + dT + " dT/stepCount: " + (dT)/len); 
    } 
} 
} 

Mã này giúp bạn xác định kích thước bộ nhớ cache dữ liệu L1. Bạn có thể đọc chi tiết hơn tại đây. https://medium.com/@behzodbekqodirov/threading-in-java-194b7db6c1de#.kzt4w8eul

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