Vectơ vectơ là gì?


188

Vài lần bây giờ, tôi đã gặp thuật ngữ này trong matlab, fortran ... một số khác ... nhưng tôi chưa bao giờ tìm thấy một lời giải thích nó có nghĩa là gì, và nó có nghĩa là gì? Vì vậy, tôi đang hỏi ở đây, vector hóa là gì và nó có nghĩa gì, ví dụ, "một vòng lặp được vector hóa" là gì?


1
@geoffspear Liên kết dường như đã được chuyển đến en.wikipedia.org/wiki/Array_programming
Tôi thích Mã

Câu trả lời:


222

Nhiều CPU có các tập lệnh "vectơ" hoặc "SIMD" áp dụng cùng một hoạt động cho hai, bốn hoặc nhiều phần dữ liệu. Các chip x86 hiện đại có các hướng dẫn SSE, nhiều chip PPC có các hướng dẫn "Altivec" và thậm chí một số chip ARM có một tập lệnh vector, được gọi là NEON.

"Vectorization" (đơn giản hóa) là quá trình viết lại một vòng lặp để thay vì xử lý một phần tử của một mảng N lần, nó xử lý (giả sử) 4 phần tử của mảng đồng thời N / 4 lần.

(Tôi đã chọn 4 vì đó là phần cứng hiện đại có khả năng hỗ trợ trực tiếp nhất; thuật ngữ "vector hóa" cũng được sử dụng để mô tả một chuyển đổi phần mềm cấp cao hơn trong đó bạn có thể chỉ trừu tượng hóa vòng lặp hoàn toàn và chỉ mô tả hoạt động trên các mảng thay vì các phần tử bao gồm họ)


Sự khác biệt giữa vectorization và unrolling loop: Hãy xem xét vòng lặp rất đơn giản sau đây thêm các phần tử của hai mảng và lưu kết quả vào mảng thứ ba.

for (int i=0; i<16; ++i)
    C[i] = A[i] + B[i];

Không kiểm soát vòng lặp này sẽ biến nó thành một cái gì đó như thế này:

for (int i=0; i<16; i+=4) {
    C[i]   = A[i]   + B[i];
    C[i+1] = A[i+1] + B[i+1];
    C[i+2] = A[i+2] + B[i+2];
    C[i+3] = A[i+3] + B[i+3];
}

Mặt khác, vector hóa nó tạo ra một cái gì đó như thế này:

for (int i=0; i<16; i+=4)
    addFourThingsAtOnceAndStoreResult(&C[i], &A[i], &B[i]);

Trong đó "addFourThingsAtOnceAndStoreResult" là một trình giữ chỗ cho bất kỳ (các) nội tại nào trình biên dịch của bạn sử dụng để chỉ định các hướng dẫn vectơ. Lưu ý rằng một số trình biên dịch có thể tự động vector hóa các vòng lặp rất đơn giản như thế này, thường có thể được kích hoạt thông qua tùy chọn biên dịch. Các thuật toán phức tạp hơn vẫn cần có sự trợ giúp từ lập trình viên để tạo mã vector tốt.


11
Sự khác biệt giữa điều này và vòng lặp uninding / unrolling là gì?
Jeremy Powell

1
Có phải sự thật là một trình biên dịch sẽ có một công việc dễ dàng hơn tự động vector hóa vòng lặp không được kiểm soát?
Nikos Athanasiou

@NikosAthanasiou: Điều đó hợp lý, nhưng nói chung, một trình biên dịch sẽ có thể tự động điều chỉnh một trong hai vòng lặp, vì cả hai đều khá đơn giản.
Stephen Canon

1
@StephenCanon làm thế nào để kiểm tra xem một số dòng có được vector hóa hay không? Nếu một người sử dụng objdump, người ta sẽ tìm kiếm gì trong đầu ra của objdump?
dùng1823664

3
@Shuklaswag: vector hóa là thứ mà trình biên dịch có thể làm cho bạn, nhưng nó cũng là thứ mà các lập trình viên tự làm một cách rõ ràng. HĐH không liên quan.
Stephen Canon

32

Vectorization là thuật ngữ để chuyển đổi một chương trình vô hướng thành một chương trình vector. Các chương trình vector hóa có thể chạy nhiều hoạt động từ một lệnh đơn, trong khi vô hướng chỉ có thể hoạt động trên các cặp toán hạng cùng một lúc.

Từ wikipedia :

Phương pháp vô hướng:

for (i = 0; i < 1024; i++)
{
   C[i] = A[i]*B[i];
}

Phương pháp Vectorized:

for (i = 0; i < 1024; i+=4)
{
   C[i:i+3] = A[i:i+3]*B[i:i+3];
}

về bản chất không giống như cách tiếp cận vô hướng? Cú pháp và tiến trình vòng lặp của bạn là khác nhau, nhưng bên dưới bạn vẫn nhân nó 4 lần. Nhưng bằng cách nào đó, nó sẽ nhanh hơn có lẽ CPU có các hướng dẫn thực hiện một số mẹo gọi là Vectorization.
mskw

Hình như tôi sẽ trả lời câu hỏi của riêng tôi ở đây. Cú pháp trong cách tiếp cận vector hóa khi trình biên dịch thấy điều đó, nó sẽ dịch nó thành các lệnh CPU được tối ưu hóa để nhân các vectơ. Giống như SIMD.
mskw

10

Nó đề cập đến khả năng thực hiện phép toán đơn lẻ trong một danh sách - hoặc "vectơ" - của các số trong một bước duy nhất. Bạn thấy nó thường xuyên với Fortran bởi vì điều đó liên quan đến điện toán khoa học, liên quan đến siêu máy tính, nơi số học véc tơ xuất hiện lần đầu tiên. Ngày nay, hầu hết các CPU máy tính để bàn đều cung cấp một số dạng số học được vector hóa, thông qua các công nghệ như SSE của Intel. GPU cũng cung cấp một dạng số học vector hóa.


7

Vector hóa được sử dụng rất nhiều trong điện toán khoa học, nơi khối dữ liệu khổng lồ cần được xử lý hiệu quả.

Trong ứng dụng lập trình thực, tôi biết nó được sử dụng trong NUMPY (không chắc chắn về người khác).

Numpy (gói cho tính toán khoa học trong python), sử dụng vector hóa để thao tác nhanh chóng với mảng n chiều, thường chậm hơn nếu được thực hiện với các tùy chọn python dựng sẵn để xử lý mảng.

mặc dù tấn giải thích được trên mạng, đây là những gì vector được định nghĩa là TRÊN TRANG TÀI LIỆU NumPy

Vectorization mô tả sự vắng mặt của bất kỳ vòng lặp rõ ràng, lập chỉ mục, v.v., trong mã - những điều này đang diễn ra, tất nhiên, chỉ là đằng sau những cảnh vụ trong mã C được tối ưu hóa, được biên dịch trước. Mã Vectorized có nhiều lợi thế, trong số đó là:

  1. mã vectorized ngắn gọn hơn và dễ đọc hơn

  2. Ít dòng mã hơn thường có nghĩa là ít lỗi hơn

  3. mã gần giống với ký hiệu toán học tiêu chuẩn hơn (thông thường, dễ dàng hơn để mã hóa các cấu trúc toán học chính xác)

  4. kết quả vector hóa trong mã số Pythonic nhiều hơn. Nếu không có vector hóa, mã của chúng ta sẽ bị lấp đầy bởi các vòng lặp không hiệu quả và khó đọc.


4

Vectorization, nói một cách đơn giản, có nghĩa là tối ưu hóa thuật toán để nó có thể sử dụng các hướng dẫn SIMD trong bộ xử lý.

AVX, AVX2 và AVX512 là các tập lệnh (intel) thực hiện cùng một hoạt động trên nhiều dữ liệu trong một lệnh. ví dụ AVX512 có nghĩa là bạn có thể hoạt động trên 16 giá trị số nguyên (4 byte) tại một thời điểm. Điều đó có nghĩa là nếu bạn có vectơ gồm 16 số nguyên và bạn muốn nhân đôi giá trị đó trong mỗi số nguyên và sau đó thêm 10 vào số nguyên đó. Bạn có thể tải các giá trị vào thanh ghi chung [a, b, c] 16 lần và thực hiện cùng một thao tác hoặc bạn có thể thực hiện cùng một thao tác bằng cách tải tất cả 16 giá trị vào các thanh ghi SIMD [xmm, ymm] và thực hiện thao tác một lần. Điều này cho phép tăng tốc tính toán của dữ liệu vectơ.

Trong vector hóa, chúng tôi sử dụng điều này cho lợi thế của mình, bằng cách sửa sang lại dữ liệu của chúng tôi để chúng tôi có thể thực hiện các hoạt động SIMD trên đó và tăng tốc chương trình.

Chỉ có vấn đề với vector hóa là điều kiện xử lý. Bởi vì điều kiện phân nhánh dòng chảy thực thi. Điều này có thể được xử lý bằng cách che dấu. Bằng cách mô hình hóa điều kiện thành một phép toán số học. ví dụ. nếu chúng ta muốn thêm 10 vào giá trị nếu nó lớn hơn 100. chúng ta có thể.

if(x[i] > 100) x[i] += 10; // this will branch execution flow.

hoặc chúng ta có thể mô hình hóa điều kiện thành phép toán số học tạo ra một vectơ điều kiện c,

c[i] = x[i] > 100; // storing the condition on masking vector
x[i] = x[i] + (c[i] & 10) // using mask

đây là ví dụ rất nhỏ mặc dù ... do đó, c là vectơ che dấu mà chúng ta sử dụng để thực hiện thao tác nhị phân dựa trên giá trị của nó. Điều này tránh phân nhánh dòng thực thi và cho phép vector hóa.

Vector hóa cũng quan trọng như Parallelization. Vì vậy, chúng ta nên sử dụng nó càng nhiều càng tốt. Tất cả các bộ xử lý hiện đại đều có hướng dẫn SIMD cho khối lượng công việc tính toán nặng. Chúng tôi có thể tối ưu hóa mã của mình để sử dụng các hướng dẫn SIMD này bằng cách sử dụng vector hóa, điều này tương tự như song song hóa mã của chúng tôi để chạy trên nhiều lõi có sẵn trên các bộ xử lý hiện đại.

Tôi muốn để lại với đề cập đến OpenMP, cho phép yo vector hóa mã bằng cách sử dụng các pragma. Tôi coi đó là một điểm khởi đầu tốt. Điều tương tự có thể được nói cho OpenACC.


0

Intel mọi người tôi nghĩ là dễ nắm bắt.

Vector hóa là quá trình chuyển đổi một thuật toán từ hoạt động trên một giá trị tại một thời điểm sang hoạt động trên một tập hợp các giá trị tại một thời điểm . Các CPU hiện đại cung cấp hỗ trợ trực tiếp cho các hoạt động của vectơ trong đó một lệnh đơn được áp dụng cho nhiều dữ liệu (SIMD).

Ví dụ, CPU có thanh ghi 512 bit có thể giữ 16 nhân đôi độ chính xác 32 bit và thực hiện một phép tính đơn lẻ.

Nhanh hơn 16 lần so với thực hiện một lệnh duy nhất tại một thời điểm. Kết hợp điều này với CPU luồng và CPU đa lõi dẫn đến các đơn đặt hàng tăng hiệu suất.

Liên kết https://software.intel.com/en-us/articles/vectorization-a-key-tool-to-improve-performance-on-modern-cpus

Trong Java, có một tùy chọn cho điều này được bao gồm trong Jdk 15 năm 2020 hoặc muộn tại JDK 16 lúc 2021.

https://bugs.openjdk.java.net/browse/JDK-8201271


-4

Xem hai câu trả lời ở trên. Tôi chỉ muốn nói thêm rằng lý do muốn thực hiện vector hóa là các hoạt động này có thể dễ dàng được thực hiện trong paraell bởi các siêu máy tính và đa bộ xử lý, mang lại hiệu suất lớn. Trên các máy tính xử lý đơn sẽ không có hiệu suất tăng.


12
"Trên các máy tính xử lý đơn sẽ không có hiệu suất tăng": không đúng. Hầu hết các bộ xử lý hiện đại đều có (phần cứng) hỗ trợ phần cứng cho vector hóa (SSE, Altivec, v.v. như được đặt tên bởi stephentyrone), có thể tăng tốc đáng kể khi sử dụng.
sleske

cảm ơn, tôi quên rằng song song cũng có thể được thực hiện ở cấp độ đó.
Larry Watanabe
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.