Bố trí hàng chính so với cột chính của ma trận


16

Trong lập trình tính toán ma trận dày đặc, có lý do nào để chọn bố cục hàng chính của bố cục trên cột không?

Tôi biết rằng tùy thuộc vào cách bố trí của ma trận được chọn, chúng ta cần viết mã phù hợp để sử dụng bộ nhớ cache hiệu quả cho mục đích tốc độ.

Bố cục chính hàng có vẻ tự nhiên và đơn giản hơn (ít nhất là với tôi). Nhưng các thư viện lớn như LAPACK được viết bằng Fortran sử dụng bố cục chính của cột, do đó phải có một số lý do để đưa ra lựa chọn này.


Nếu chúng ta xem xét tính toán b = A * x với vectơ cột x, đối với hàng A chính, chúng ta có thể sử dụng các sản phẩm bên trong của vectơ, A (i, :) ^ T x để lấy b (i); đối với cột chính, chúng ta có thể chỉ cần các vectơ nhân vô hướng, sum_i A (:, i) x (i). Dường như với tôi cột lớn là tốt hơn nhiều! Bạn nghĩ sao?
Hui Zhang

Rèn luyện bản thân để thích chuyên ngành. Thật dễ dàng khi bạn hình dung các vectơ dưới dạng cột hoặc hoán vị của chúng dưới dạng hàng. Nó làm cho trực quan hóa nhân ma trận rất đơn giản, và làm cho nó dễ dàng để theo dõi nhiều toán học được xuất bản.
Mike Dunlavey

Câu trả lời:


18

Bố cục chính của cột là lược đồ được Fortran sử dụng và đó là lý do tại sao nó được sử dụng trong LAPACK và các thư viện khác.

Nói chung, hiệu quả hơn về mặt sử dụng băng thông bộ nhớ và hiệu năng bộ đệm để truy cập các phần tử của một mảng theo thứ tự chúng được đặt trong bộ nhớ. Tùy thuộc vào cách ma trận của bạn được lưu trữ, bạn sẽ muốn chọn các thuật toán tận dụng lợi thế này.

lưu trữ nội bộ Lưu trữ nội bộ của định dạng chính cột


11

Trong chân không mà không xem xét bất kỳ phần mềm hiện có nào, không có lý do nào để thích cột chính hơn hàng chính theo quan điểm mã. Tuy nhiên, hầu hết các tài liệu toán học được viết theo cách nhóm các vectơ thành một ma trận bằng cách lưu trữ chúng dưới dạng cột thay vì các hàng. Ví dụ khi bạn viết eigenvalue đầy đủ phương trình , các XMộtX= =XΛXma trận chứa tất cả các hàm riêng được viết ra trong các cột. Bạn không bao giờ thực sự thấy nó được viết theo cách khác (mặc dù tôi nghe rằng những người thống kê như vectơ hàng). Do đó, điều tự nhiên là phần mềm sớm nhất giả định định dạng chính của cột để nếu bạn có một ma trận là một tập các vectơ, thì việc lưu trữ bất kỳ vectơ đơn lẻ nào là liền kề nhau. Vì vậy, tôi tưởng tượng rằng truyền thống này đã được tiếp tục cho đến ngày nay và nếu bạn muốn tương tác với Fortran của bạn, bạn muốn sử dụng cột chính. Vì vậy, khá nhiều tất cả các đại số tuyến tính số hiệu quả cao được thực hiện trong cột chính.

Lý do C là hàng chính là một phần của hệ quả của cú pháp mảng; bạn khai báo một mảng 3 hàng bằng 2 cột như double a[3][2]và các chỉ mục sau thay đổi nhanh hơn các chỉ số trước đó, điều này đối với mảng 2D làm cho nó trở thành hàng chính. Kết hợp điều này với thứ tự đọc phương Tây tự nhiên từ trái sang phải, nó làm cho hàng lớn có vẻ tự nhiên hơn.


2
Tôi nghĩ rằng đây là những lập luận nghèo nàn. Việc chỉ số cuối cùng trong '' 'nhân đôi [3] [2]' '' thay đổi nhanh nhất không phải là một sự trùng hợp ngẫu nhiên - đó là một quyết định thiết kế thú vị theo cách tương tự như đó là một quyết định thiết kế có ý thức ở Fortran làm theo cách khác khi bạn có một mảng '' 'thực (3,2)' ''.
Wolfgang Bangerth

1
Hơn nữa, nó không còn đúng nữa mà gần như tất cả các đại số tuyến tính số hiệu quả cao là cột chính. Điều này có thể vẫn đúng với BLAS và LAPACK, nhưng nó hoàn toàn không đúng với mọi thư viện đại số tuyến tính chính đã xuất hiện trong 15 năm qua: ví dụ, cả PETSc và Trilinos đều sử dụng các định dạng lưu trữ ma trận thưa thớt chính.
Wolfgang Bangerth

Tôi biết rằng quy ước C là một quyết định có ý thức, có lẽ dựa trên trật tự đọc tự nhiên. Tôi có nghĩa là nó có thể không được thiết kế với đại số tuyến tính trong tâm trí, làm cho nó là một sự trùng hợp ngẫu nhiên mà nó là hàng lớn. Thứ hai, tôi không có ý định tranh luận về các ma trận thưa thớt, chỉ dày đặc. Để thưa thớt, đó là một chút hỗn hợp ngoài kia, với cả định dạng hàng và cột được nén.
Victor Liu

5
Không tin vào điểm này, nhưng C ban đầu là ngôn ngữ hệ thống, dựa trên các ngôn ngữ B và BCPL trước đó, chạy trên các hệ thống như PDP-11 ban đầu không có số dấu phẩy động. Để nói rằng họ đã thiết kế nó với số lượng trong tâm trí là khá căng.
Victor Liu

7
Ở đó, v.v ... Lý do ma trận trong C di chuyển chỉ số cuối cùng nhanh nhất là vì C không có ma trận. Nó có các vectơ của vectơ, có thể được triển khai trong suốt như các khối bộ nhớ vững chắc, hoặc như các mảng của con trỏ tới các mảng. Làm cho thứ tự chỉ mục tương thích với Fortran là (tôi đoán) thậm chí không phải trên radar của Dennis Ritchie.
Mike Dunlavey

2

Cột-thứ tự chính dường như là tự nhiên hơn. Ví dụ: giả sử nếu bạn muốn lưu phim vào tập tin bằng hình ảnh thì bạn đang sử dụng thứ tự cột và điều đó rất trực quan và không ai sẽ lưu nó theo thứ tự chính hàng.

Nếu bạn là lập trình viên trong C / C ++, bạn nên sử dụng một số thư viện cấp cao hơn cho ma trận (Eigen, Armadillo, ...) với thứ tự cột chính mặc định. Chỉ có maniac mới sử dụng các con trỏ C thô với thứ tự chính hàng, mặc dù C / C ++ cung cấp một cái gì đó nhắc nhở việc lập chỉ mục ma trận.

Để đơn giản, mọi thứ với thứ tự hàng lớn nên được coi là ít nhất là hình thành kỳ lạ. Slice by lát đơn giản là thứ tự tự nhiên và nó có nghĩa là thứ tự chính cột (như Fortran). Cha / mẹ của chúng tôi đã có một lý do rất tốt tại sao họ chọn nó.

Thật không may trước khi nó trở nên rõ ràng một số thư viện thú vị đã được tạo theo thứ tự hàng lớn, có thể là do thiếu kinh nghiệm.

Để làm rõ việc nhớ lại định nghĩa của thứ tự hàng chính trong đó chỉ số bên phải thay đổi nhanh hơn trong một bước qua bộ nhớ, ví dụ A (x, y, z) đó là chỉ mục z, điều đó có nghĩa là trong các pixel bộ nhớ từ các lát khác nhau liền kề, chúng ta sẽ làm gì không muốn Đối với phim A (x, y, t) chỉ số cuối cùng là thời gian t. Không khó để tưởng tượng rằng đơn giản là không thể lưu phim ở chế độ hàng lớn.


2

m×n

  • mTôi,jTôi×m+j
  • mTôi,jj×n+Tôi

Bây giờ hãy tưởng tượng thuật toán sau:

for i from 1 to m
   for j from 1 to n
      do something with m(i,j)

Tôi×m+j

Kết luận:

  1. vâng, nó có một tầm quan trọng, nhưng sự lựa chọn phụ thuộc vào cách dữ liệu được tích lũy. Đối với ví dụ trước, nếu thứ tự cột được sử dụng, điều bạn có thể làm chỉ đơn giản là hoán đổi hai vòng.

  2. quy tắc ngón tay cái: chỉ số thay đổi nhanh chóng nên được ánh xạ tới các vị trí liên tiếp trong bộ nhớ.

  3. quan trọng hơn, việc đo lường / đo điểm chuẩn tác động của sự lựa chọn là cơ bản, vì nó phụ thuộc vào nhiều tham số (kích thước của dữ liệu, kích thước của bộ đệm, cách ngôn ngữ được sử dụng ánh xạ nhiều chỉ mục vào một chỉ mục tuyến tính, cách vận hành hệ thống quản lý bộ nhớ ảo, cách các vòng lặp được lồng trong thư viện đại số tuyến tính mà bạn sử dụng ...)

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.