Hiệu suất vòng lặp mã C [tiếp theo]


83

Câu hỏi này tiếp tục cho câu hỏi của tôi ở đây (theo lời khuyên của Mystical):

Hiệu suất vòng lặp mã C


Tiếp tục câu hỏi của tôi, khi tôi sử dụng hướng dẫn đóng gói thay vì hướng dẫn vô hướng, mã sử dụng bản chất sẽ trông rất giống:

for(int i=0; i<size; i+=16) {
    y1 = _mm_load_ps(output[i]);
    …
    y4 = _mm_load_ps(output[i+12]);

    for(k=0; k<ksize; k++){
        for(l=0; l<ksize; l++){
            w  = _mm_set_ps1(weight[i+k+l]);

            x1 = _mm_load_ps(input[i+k+l]);
            y1 = _mm_add_ps(y1,_mm_mul_ps(w,x1));
            …
            x4 = _mm_load_ps(input[i+k+l+12]);
            y4 = _mm_add_ps(y4,_mm_mul_ps(w,x4));
        }
    }
    _mm_store_ps(&output[i],y1);
    …
    _mm_store_ps(&output[i+12],y4);
    }

Hiệu suất đo được của hạt nhân này là khoảng 5,6 hoạt động FP mỗi chu kỳ, mặc dù tôi mong đợi nó chính xác gấp 4 lần hiệu suất của phiên bản vô hướng, tức là 4,1,6 = 6,4 FP ops mỗi chu kỳ.

Có tính đến sự di chuyển của hệ số trọng lượng (cảm ơn bạn đã chỉ ra điều đó), lịch trình sẽ như sau:

lịch trình

Có vẻ như lịch trình không thay đổi, mặc dù có thêm lệnh sau movssthao tác di chuyển giá trị trọng số vô hướng sang thanh ghi XMM và sau đó sử dụng shufpsđể sao chép giá trị vô hướng này trong toàn bộ vectơ. Có vẻ như vectơ trọng số đã sẵn sàng để được sử dụng mulpskịp thời có tính đến độ trễ chuyển đổi từ tải sang miền dấu phẩy động, vì vậy điều này sẽ không phát sinh thêm bất kỳ độ trễ nào.

Các lệnh movaps(căn chỉnh, đóng gói) addpsvà các mulpshướng dẫn được sử dụng trong hạt nhân này (được kiểm tra bằng mã lắp ráp) có cùng độ trễ và thông lượng như các phiên bản vô hướng của chúng, vì vậy điều này cũng sẽ không phát sinh thêm bất kỳ độ trễ nào.

Có ai có ý kiến ​​về nơi mà chu kỳ bổ sung này cho mỗi 8 chu kỳ được sử dụng, giả sử hiệu suất tối đa mà hạt nhân này có thể nhận được là 6,4 FP ops mỗi chu kỳ và nó đang chạy ở 5,6 FP ops mỗi chu kỳ?


Nhân tiện đây là lắp ráp thực tế trông như thế nào:

…
Block x: 
  movapsx  (%rax,%rcx,4), %xmm0
  movapsx  0x10(%rax,%rcx,4), %xmm1
  movapsx  0x20(%rax,%rcx,4), %xmm2
  movapsx  0x30(%rax,%rcx,4), %xmm3
  movssl  (%rdx,%rcx,4), %xmm4
  inc %rcx
  shufps $0x0, %xmm4, %xmm4               {fill weight vector}
  cmp $0x32, %rcx 
  mulps %xmm4, %xmm0 
  mulps %xmm4, %xmm1
  mulps %xmm4, %xmm2 
  mulps %xmm3, %xmm4
  addps %xmm0, %xmm5 
  addps %xmm1, %xmm6 
  addps %xmm2, %xmm7 
  addps %xmm4, %xmm8 
  jl 0x401ad6 <Block x> 
…

Vì vậy, tôi đoán câu hỏi bây giờ là: "Tại sao shufpslệnh thêm 1 chu kỳ sau mỗi 1,6 lần lặp?" Đó là một trong những khó khăn ...
Mysticial

tôi hy vọng nó sẽ không có chi phí vì đầu ra của shufpsphải trực tiếp có sẵn cho multpsop vì nó là cả miền FP
Ricky

Dễ dàng tìm ra. Đảm bảo rằng vectơ trọng số không chứa bất kỳ giá trị giá trị không chuẩn hóa nào. Hãy thử vòng lặp mà không có hướng dẫn xáo trộn. Nó sẽ không tạo ra bất kỳ kết quả hữu ích nào, nhưng có thể việc bạn tìm thấy hướng dẫn nào khiến bạn tốn thêm chu kỳ (tất nhiên là tôi nghi ngờ sự xáo trộn).
Gunther Piez

@Mystical: Tôi thấy 0,75 chu kỳ mỗi lần lặp vòng lặp được thêm vào. (Chẳng phải nó nhận xét của tôi về việc sử dụng 5 chu kỳ thay vì 4 mà dẫn bạn đến câu trả lời của bạn ở đó ... :-))
Gunther Piez

3
Đối với một, bây giờ bạn đang đòi hỏi gấp 4 lần băng thông bộ nhớ cache. Kích thước dữ liệu lớn như thế nào? Chúng có vừa với bộ đệm L1 không?
Mysticial

Câu trả lời:


3

Hãy thử sử dụng cấu hình EMON trong Vtune hoặc một số công cụ tương đương như oprof

Hồ sơ EMON (Giám sát sự kiện) => giống như một công cụ dựa trên thời gian, nhưng nó có thể cho bạn biết sự kiện hiệu suất nào đang gây ra sự cố. Mặc dù vậy, trước tiên bạn nên bắt đầu với hồ sơ dựa trên thời gian, để xem liệu có hướng dẫn cụ thể nào xuất hiện hay không. (Và có thể là các sự kiện liên quan cho bạn biết tần suất ngừng nghỉ hưu tại IP đó.)

Để sử dụng cấu hình EMON, bạn phải xem qua một danh sách các sự kiện, từ "các nghi phạm thông thường" đến ...

Ở đây, tôi sẽ bắt đầu với các lỗi bộ nhớ cache, căn chỉnh. Tôi không biết liệu bộ xử lý bạn đang sử dụng có bộ đếm hạn chế cổng RF hay không - nhưng tôi đã thêm cấu hình EMON từ lâu và tôi không biết chúng đang theo kịp bằng cách thêm các sự kiện phù hợp với vi kiến ​​trúc.

Nó cũng có thể là giao diện người dùng, tìm nạp hướng dẫn, ngừng hoạt động. Dù sao thì bao nhiêu byte trong các hướng dẫn này? Cũng có các sự kiện EMON cho điều đó.


Trả lời bình luận rằng Nehalem VTune không thể xem các sự kiện L3: không đúng. Đây là nội dung tôi đã thêm vào bình luận, nhưng không phù hợp:

Trên thực tế, CÓ bộ đếm hiệu suất cho LL3 / L3 $ / cái gọi là Uncore. Tôi sẽ vô cùng ngạc nhiên nếu VTune không hỗ trợ chúng. Xem http://software.intel.com/sites/products/collateral/hpc/vtune/performance_analysis_guide.pdftrỏ tới VTune và các công cụ khác như PTU. Trên thực tế, ngay cả khi không có sự kiện LL3, như David Levinthal nói: "Bộ xử lý Intel® Core ™ i7 có" sự kiện độ trễ "rất giống với sự kiện EAR dữ liệu gia đình bộ xử lý Itanium®. Sự kiện này tải mẫu, ghi lại số chu kỳ giữa việc thực hiện lệnh và thực tế cung cấp dữ liệu. Nếu độ trễ đo được lớn hơn độ trễ tối thiểu được lập trình thành MSR 0x3f6, bit 15: 0, thì bộ đếm sẽ tăng lên. Tràn bộ đếm hỗ trợ cơ chế PEBS và tiếp theo sự kiện thỏa mãn ngưỡng độ trễ, độ trễ đo được, địa chỉ ảo hoặc tuyến tính và nguồn dữ liệu được sao chép vào 3 thanh ghi bổ sung trong bộ đệm PEBS. Vì địa chỉ ảo được ghi vào một vị trí đã biết, trình điều khiển lấy mẫu cũng có thể thực hiện một bản dịch từ ảo sang thực và nắm bắt địa chỉ thực. Địa chỉ thực xác định vị trí nhà NUMA và về nguyên tắc cho phép phân tích chi tiết về việc chiếm dụng bộ nhớ đệm. "Ở trang 35, anh ấy cũng chỉ ra các sự kiện VTune như L3 CACHE_HIT_UNCORE_HIT và L3 CACHE_MISS_REMOTE_DRAM. Đôi khi bạn cần tra cứu số mã và lập trình chúng vào giao diện cấp thấp hơn của VTune, nhưng tôi nghĩ trong trường hợp này, nó hiển thị trong giao diện người dùng đẹp.


OK, trong http://software.intel.com/en-us/forums/showthread.php?t=77700&o=d&s=lr, một lập trình viên VTune ở Nga (tôi nghĩ) "giải thích" rằng bạn không thể lấy mẫu trên Uncore sự kiện.

Anh ấy sai - ví dụ, bạn có thể chỉ bật một CPU và lấy mẫu một cách có ý nghĩa. Tôi cũng tin rằng có khả năng đánh dấu dữ liệu bị thiếu L3 khi nó quay trở lại CPU. Trên thực tế, về tổng thể, L3 biết CPU mà nó đang trả về dữ liệu, vì vậy bạn chắc chắn có thể lấy mẫu. Bạn có thể không biết siêu phân luồng nào, nhưng một lần nữa bạn có thể tắt, chuyển sang chế độ luồng đơn.

Nhưng có vẻ như, một điều khá phổ biến, bạn sẽ phải làm việc AROUND VTune, không phải với nó, để làm điều này.

Hãy thử lập hồ sơ độ trễ trước. Đó là hoàn toàn bên trong CPU và những người làm VTune không chắc đã làm nó rối tung lên quá nhiều.

Và, tôi nói lại một lần nữa, rất có thể vấn đề của bạn nằm ở cốt lõi, không phải ở L3. Vì vậy, VTune sẽ có thể xử lý điều đó.


Hãy thử "Kế toán chu kỳ" cho mỗi Levinthal.


Cảm ơn phản ứng của bạn. Tôi sử dụng VTune để phân tích ứng dụng của mình, nhưng vấn đề với kiến ​​trúc nehalem là bộ đệm L3 thuộc về off-corephần lõi, vì vậy không có bộ đếm sự kiện hiệu suất nào có sẵn cho phần này. Do đó, thật khó để ước tính bộ nhớ cache bỏ sót etcetera.
Ricky

Trên thực tế, CÓ bộ đếm hiệu suất cho LL3 / L3 $ / cái gọi là Uncore. Tôi sẽ vô cùng ngạc nhiên nếu VTune không hỗ trợ chúng. Xem software.intel.com/sites/products/collateral/hpc/vtune/…
Krazy Glew

Tôi đã viết nhiều hơn những gì sẽ phù hợp với bình luận, cố gắng chuyển nó đến câu trả lời và xóa bình luận ban đầu, nhưng bình luận chỉ có thể được chỉnh sửa trong 5 phút. Phiên bản ngắn: VTune cho phép bạn xem các lần bỏ sót bộ nhớ đệm L3. Ngay cả khi không hỗ trợ Uncore, sử dụng cấu hình độ trễ - và nó có hỗ trợ Uncore.
Krazy Glew

Và nhìn chung, tôi nghi ngờ rằng vấn đề của bạn không phải là bộ nhớ cache L3 bị bỏ lỡ. Nhiều khả năng là một sự kiện giao diện người dùng.
Krazy Glew

@KrazyGlew: Bạn đoán đúng rồi, anh ấy là một chàng trai người Nga đến từ Liên bang Nga. Đây là hồ sơ của anh ấy trên LinkedIn - linkedin.com/in/vtsymbal
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.