Hàm nội tại
svlsr_u32_z trong bộ mở rộng SVE (Scalable Vector Extension) của ARM thực hiện thao tác dịch phải logic trên các phần tử nguyên không dấu 32 bit (uint32_t) theo từng phần tử trong vector, đồng thời sử dụng một mặt nạ điều kiện (predicate mask) để kiểm soát các vị trí được xử lý. Các phần tử không được kích hoạt bởi mặt nạ sẽ có kết quả bằng 0. Ký hiệu "lsr" trong tên hàm là viết tắt của "Logical Shift Right", còn ký tự "z" ám chỉ chế độ zeroing – ghi đè kết quả về 0 tại những vị trí bị vô hiệu hóa.
Cú pháp khai báo
svuint32_t svlsr_u32_z(
svbool_t pg, // Mặt nạ nhị phân: xác định phần tử nào được xử lý
svuint32_t operand, // Vector dữ liệu đầu vào (32-bit unsigned)
uint32_t amount // Số bit dịch phải (giá trị vô hướng, từ 0 đến 31)
);
Giải thích tham số
-
pg – Mặt nạ điều kiện kiểu
svbool_t- Nếu bit mặt nạ tại vị trí
ilàtrue(1): phần tử tương ứng trongoperandsẽ được dịch phải logicamountbit. - Nếu bit mặt nạ là
false(0): kết quả tại vị trí đó sẽ là0, bất kể giá trị ban đầu.
- Nếu bit mặt nạ tại vị trí
-
operand – Vector chứa các giá trị kiểu
uint32_tcần dịch phải. -
amount – Số lượng bit dịch phải, áp dụng đồng nhất cho mọi phần tử hợp lệ. Giá trị phải nằm trong khoảng
0 ≤ amount < 32; nếu vượt quá sẽ dẫn đến hành vi không xác định.
Nguyên lý hoạt động
Phép dịch phải logic di chuyển toàn bộ bit của mỗi phần tử sang phải, và điền bit 0 vào các vị trí cao bị trống. Điều này khác với dịch phải số học (arithmetic shift), vốn giữ nguyên bit dấu. Với
svlsr_u32_z, hành vi cụ thể như sau:
- Tại các vị trí có mặt nạ bật: thực hiện
operand[i] >> amount. - Tại các vị trí mặt nạ tắt: kết quả cố định là
0.
Ví dụ minh họa
Giả sử:
- Dữ liệu vào:
[0x80000000, 0x0000000F, 0xABCD1234, 0x12345678] - Mặt nạ:
[true, true, false, true] - Số bit dịch:
4
- Phần tử 0:
0x80000000 >> 4 = 0x08000000 - Phần tử 1:
0x0000000F >> 4 = 0x00000000 - Phần tử 2: mặt nạ tắt →
0x00000000 - Phần tử 3:
0x12345678 >> 4 = 0x01234567
[0x08000000, 0x00000000, 0x00000000, 0x01234567].
Ứng dụng thực tế
Một trường hợp điển hình là trích xuất 16 bit cao từ mỗi số 32 bit bằng cách dịch phải 16 vị trí:
#include <arm_sve.h>
#include <stdint.h>
void lay_16bit_cao(uint32_t* ket_qua, const uint32_t* nguon, size_t n) {
size_t idx = 0;
svuint32_t vec_kq;
do {
// Tạo mặt nạ cho đoạn dữ liệu hiện tại
svbool_t pg = svwhilelt_b32(idx, n);
// Đọc dữ liệu vào vector
svuint32_t vec_in = svld1_u32(pg, nguon + idx);
// Dịch phải 16 bit, mặt nạ tắt thì đặt về 0
vec_kq = svlsr_u32_z(pg, vec_in, 16);
// Ghi kết quả ra bộ nhớ
svst1_u32(pg, ket_qua + idx, vec_kq);
// Tiến tới đoạn tiếp theo
idx += svcntw();
} while (svptest_any(svptrue_b32(), svwhilelt_b32(idx, n)));
}
Sau khi thực thi, mảng
ket_qua sẽ chứa các giá trị 16 bit cao của từng phần tử trong nguon, ví dụ: 0xABCD1234 → 0x0000ABCD.
Lưu ý quan trọng
- Chế độ zeroing: Suffix "z" đảm bảo các phần tử ngoài vùng mặt nạ luôn trả về 0. Nếu dùng phiên bản không có "z" như
svlsr_u32, giá trị cũ có thể được giữ lại. - Dịch bit đồng nhất: Biến
amountlà giá trị vô hướng – tất cả phần tử đều dịch cùng số bit. Để dịch khác nhau theo từng phần tử, hãy dùngsvlsrv_u32_zvới vector số bit dịch. - Tính linh hoạt về độ dài vector: SVE tự động điều chỉnh độ dài vector tùy nền tảng (128, 256, 512 bit...). Mã nguồn không cần sửa đổi khi chạy trên các thiết bị khác nhau.
- Phân biệt dịch phải logic và số học: Dùng
lsrcho số không dấu,asrcho số có dấu để tránh sai sót về giá trị âm.
Kết luận
svlsr_u32_z là một hàm nội tại mạnh mẽ trong hệ sinh thái SVE, hỗ trợ xử lý song song hiệu quả các thao tác dịch bit trên dữ liệu lớn. Nhờ kết hợp giữa tính toán vector và điều khiển qua mặt nạ, nó rất phù hợp cho các tác vụ như trích xuất bit, chuẩn hóa dữ liệu hoặc tối ưu vòng lặp xử lý mảng kiểu nguyên.