2016-05-18 12 views
6

Đây là mã tôi đã viết:Tăng tốc độ nhân bản ma trận với OpenMP và phương pháp chặn: Tôi có thể làm tốt hơn không?

#include <omp.h> 
void matrix_multi(int c[][TSIZE], int a[][TSIZE], int b[][TSIZE]) 
{ 
    int B=8; 

    int i, j, k,i1,j1,k1; 
#pragma omp parallel for private(i,j,k,i1,j1,k1) schedule(auto) collapse(3) 
    for (i=0; i<TSIZE; i+=B) 
    for (j=0; j<TSIZE; j+=B) 
     for (k=0; k<TSIZE; k+=B) 
     for (i1=i;i1<i+B;i1++) 
      for (j1=j;j1<j+B;j1++) 
      { 
       int sum=0; 
       for (k1=k;k1<k+B;k1++) 
       { 
        sum+=a[i1][k1]*b[k1][j1]; 
       } 
       c[i1][j1]+=sum; 
      } 

} 

Câu hỏi của tôi là: Tôi có thể có được một hiệu suất tốt hơn với một số thao tác hơn nữa trên ba vòng bên trong?

+0

Bạn đã đo hiệu suất bạn nhận được chưa? Đối với phép nhân ma trận, bạn có thể so sánh với hiệu suất đỉnh lý thuyết. – Zulan

+0

Tôi không tin mã này là chính xác: chỉ thị 'collapse (3)' song song trên 3 chỉ mục 'i',' j' và 'k'. Điều này có nghĩa là bạn được đảm bảo rằng không có cặp 'i, j, k' nào giống hệt nhau sẽ được xử lý bởi hai luồng khác nhau. Tuy nhiên, bạn có thể có cùng cặp 'i, j' với một' k' khác nhau cho hai luồng. Và điều này sẽ dẫn đến tình trạng chạy đua khi cập nhật 'c [i1] [j1]' ... – Gilles

+0

[Video khóa học đặc biệt này] (http://ocw.mit.edu/courses/electrical-engineering-and-computer- science/6-172-performance-engineering-of-software-systems-fall-2010/video-lectures/lecture-1-matrix-multiply-a-case-study /) hoàn toàn dành riêng cho việc cải thiện tốc độ nhân bản ma trận. – displayName

Trả lời

3

Đại số tuyến tính là một trong những máy tính hoạt động phổ biến nhất hoạt động. Trong các trò chơi và thư viện đồ họa, nó là hoạt động phổ biến nhất. Nó đã được nghiên cứu và tối ưu hóa rất nhiều, với toàn bộ nhóm nghiên cứu dành riêng cho nó.

Nếu bạn quan tâm đến tốc độ, bạn nên thực hiện phép nhân ma trận với thư viện BLAS. Một số trong những điều mà một thư viện BLAS sẽ tối ưu hóa cho:

  • giảm thiểu bộ nhớ cache bỏ lỡ bằng cách thực hiện phép nhân ma trận trong khối chứ không phải lặp trên toàn bộ ma trận
  • tối ưu hóa kích thước khối cho bộ nhớ cache kích thước của máy tính
  • nếu máy tính/CPU có nhiều cấp độ bộ nhớ cache, sử dụng nhiều cấp độ kích thước khối được tối ưu hóa
  • sử dụng SIMD hướng dẫn nếu có sẵn trên CPU

Lưu ý rằng song song không có trong danh sách. Điều này là bởi vì trong truy cập bộ nhớ máy tính ngày nay là chậm hơn so với CPU. Bạn sẽ thấy hiệu suất kém hơn với openmp do phí chuyển đổi ngữ cảnh.

1

Dường như bạn ở xa hoàn toàn được tối ưu hóa. Bạn đã thử vòng lặp unroll, vòng lặp đảo ngược, vv?

Bạn có thể tham khảo liên kết sau để tối ưu hóa từng bước về nhân ma trận.

http://wiki.cs.utexas.edu/rvdg/HowToOptimizeGemm/

+0

Tôi đã nghiên cứu điều này trong một ngày và đã thực hiện rất nhiều thử nghiệm. Thật không may tôi nghĩ rằng đó là khó khăn (hoặc ra khỏi khả năng của tôi) để khai thác OpenMP int phương pháp này. Nó thực hiện một chút tồi tệ hơn so với mã với openMP. –

+0

@HuanmingSong Liên kết đang tối ưu hóa chuỗi GEMM đơn lẻ. Với GEMM luồng đơn được tối ưu hóa, bạn có thể sử dụng OpenMP để cải thiện hiệu suất trên các CPU đa lõi. – kangshiyin

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