Trong SSE3, hướng dẫn PALIGNR thực hiện như sau:_mm_alignr_epi8 (PALIGNR) tương đương trong AVX2
PALIGNR concatenates the destination operand (the first operand) and the source operand (the second operand) into an intermediate composite, shifts the composite at byte granularity to the right by a constant immediate, and extracts the right-aligned result into the destination.
Tôi hiện đang ở giữa porting mã SSE4 tôi để sử dụng hướng dẫn AVX2 và làm việc trên 256bit đăng ký thay vì 128bit. Naively, tôi tin rằng chức năng nội tại _mm256_alignr_epi8
(VPALIGNR) thực hiện các hoạt động tương tự như _mm_alignr_epi8
chỉ trên thanh ghi 256bit. Đáng buồn thay tuy nhiên, đó không phải là chính xác trường hợp. Trong thực tế, _mm256_alignr_epi8
xử lý thanh ghi 256bit là 2 thanh ghi 128bit và thực hiện 2 thao tác "căn chỉnh" trên hai thanh ghi 128bit lân cận. Thực hiện hiệu quả hoạt động tương tự như _mm_alignr_epi8
nhưng trên 2 thanh ghi cùng một lúc. Nó thể hiện rõ nhất ở đây: _mm256_alignr_epi8
Hiện nay giải pháp của tôi là tiếp tục sử dụng _mm_alignr_epi8
bằng cách phân chia các YMM (256bit) đăng ký vào hai XMM (128bit) đăng ký (cao và thấp), như vậy:
__m128i xmm_ymm1_hi = _mm256_extractf128_si256(ymm1, 0);
__m128i xmm_ymm1_lo = _mm256_extractf128_si256(ymm1, 1);
__m128i xmm_ymm2_hi = _mm256_extractf128_si256(ymm2, 0);
__m128i xmm_ymm_aligned_lo = _mm_alignr_epi8(xmm_ymm1_lo, xmm_ymm1_hi, 1);
__m128i xmm_ymm_aligned_hi = _mm_alignr_epi8(xmm_ymm2_hi, xmm_ymm1_lo, 1);
__m256i xmm_ymm_aligned = _mm256_set_m128i(xmm_ymm_aligned_lo, xmm_ymm_aligned_hi);
Điều này làm việc, nhưng phải có một cách tốt hơn, phải không? Có một hướng dẫn AVX2 "tổng quát" có lẽ nên sử dụng để có được kết quả tương tự không?
yup, đó là giải pháp tương tự. nhưng nếu đây là cách duy nhất thì nó có vẻ như một sự giám sát lớn bởi các nhà thiết kế của các chỉ dẫn AVX2 – eladidan
Tôi không thể làm được điều này để biên dịch ... Tôi nhận được lỗi biên dịch: "lỗi thảm khốc: tham số nội tại phải là giá trị ngay lập tức" trên dòng sau: "__m128i vouth = _mm_alignr_epi8 (v0l, v0h, n);". Ngụ ý, bởi vì n không phải là một sự bất tử. Làm thế nào bạn có thể bỏ qua điều này? Tôi đang sử dụng bộ biên dịch Intel C++ – eladidan
Nó hoạt động với tôi, miễn là n là hằng số biên dịch - tôi đang sử dụng trình biên dịch ICC của Intel, nhưng biên dịch thành C thay vì C++ nếu điều đó tạo ra bất kỳ sự khác biệt nào, và nó cũng làm việc cho tôi với gcc. –