Một câu trả lời dài hơn một chút giải thích tại sao nó hiệu quả hơn khi có hầu hết các chỉ số bên trái thay đổi nhanh nhất. Có hai điều quan trọng mà bạn cần hiểu.
Đầu tiên, MATLAB (và Fortran, nhưng không phải C và hầu hết các ngôn ngữ lập trình khác) lưu trữ các mảng trong bộ nhớ theo "thứ tự chính của cột". ví dụ: nếu A là ma trận 2 nhân 3, thì các mục nhập sẽ được lưu trong bộ nhớ theo thứ tự
A (1,1,1)
A (2,1,1)
A (1,2,1)
A (2,2,1)
A (1,3,1)
A (2,3,1)
A (1,1,2)
A (2,1,2)
...
A (2,3,10)
Sự lựa chọn thứ tự chính của cột này là tùy ý - chúng ta có thể dễ dàng chấp nhận quy ước "thứ tự chính hàng" và trên thực tế đó là những gì được thực hiện trong C và một số ngôn ngữ lập trình khác.
Điều quan trọng thứ hai mà bạn cần hiểu là các bộ xử lý hiện đại không truy cập bộ nhớ một vị trí tại một thời điểm, mà tải và lưu trữ "các dòng bộ đệm" gồm 64 hoặc thậm chí 128 byte liền kề (8 hoặc 16 số dấu phẩy động chính xác kép) tại một thời điểm từ bộ nhớ. Các khối dữ liệu này được lưu trữ tạm thời trong bộ nhớ cache nhanh và ghi lại khi cần. (Trong thực tế, kiến trúc bộ đệm hiện khá phức tạp với tối đa 3 hoặc 4 cấp bộ nhớ đệm, nhưng ý tưởng cơ bản có thể được giải thích bằng bộ đệm một cấp của loại máy tính có trong những ngày còn trẻ.)
Một
Nếu các vòng lặp được lồng nhau sao cho vòng lặp trong cùng cập nhật chỉ mục hàng, thì các mục mảng sẽ được truy cập theo thứ tự A (1,1), A (2.1), A (3,1), ... Khi mục đầu tiên A (1,1) được truy cập, hệ thống sẽ đưa một dòng bộ đệm chứa A (1,1), A (2.1), ..., A (8.1) vào bộ đệm từ bộ nhớ chính . 8 lần lặp tiếp theo của vòng lặp trong cùng hoạt động trên dữ liệu này mà không cần chuyển thêm bộ nhớ chính.
Nếu thay thế, chúng ta cấu trúc các vòng lặp để chỉ số cột thay đổi trong vòng lặp trong cùng, thì các mục nhập của A sẽ được truy cập theo thứ tự A (1,1), A (1,2), A (1,3 ), ... Trong trường hợp này, lần truy cập đầu tiên sẽ đưa A (1,1), A (2.1), ..., A (8.1) vào bộ nhớ cache từ bộ nhớ chính, nhưng 7/8 những mục này sẽ không được sử dụng. Việc truy cập vào A (1,2) trong lần lặp thứ hai sau đó sẽ mang lại 8 mục khác từ bộ nhớ chính, v.v. Vào thời điểm mã xung quanh hoạt động ở hàng 2 của ma trận, mục A (2.1) có thể bị xóa khỏi bộ đệm để nhường chỗ cho các dữ liệu cần thiết khác. Kết quả là, mã đang tạo ra lưu lượng truy cập gấp 8 lần khi cần thiết.
Một số trình biên dịch tối ưu hóa có khả năng tự động tái cấu trúc các vòng lặp để tránh vấn đề này.
Nhiều thuật toán đại số tuyến tính số cho phép nhân và nhân tử ma trận có thể được tối ưu hóa để hoạt động hiệu quả với sơ đồ đặt hàng chính hoặc cột chính tùy thuộc vào ngôn ngữ lập trình. Làm điều này sai cách có thể có tác động tiêu cực đáng kể đến hiệu suất.
For
các vòng lặp rất chậm trong MATLAB. Bạn nên tránh các vòng lặp rõ ràng trong MATLAB bất cứ khi nào có thể. Thay vào đó, thông thường một vấn đề có thể được thể hiện dưới dạng các phép toán ma trận / vectơ. Đó là cách MATLABic. Ngoài ra còn có rất nhiều hàm dựng sẵn để khởi tạo ma trận, v.v. Ví dụ, có một hàm, những cái () , sẽ đặt tất cả các phần tử của ma trận thành 1 (bằng cách mở rộng, thành bất kỳ giá trị nào bằng phép nhân (vô hướng nhân với ma trận tất cả những người)). Nó cũng hoạt động trên các mảng 3 chiều (mà tôi nghĩ bao gồm ví dụ ở đây).