(Tôi là một newbie để SSE/asm, lời xin lỗi nếu điều này là rõ ràng hoặc không cần thiết)transpose cho 8 thanh ghi của các nguyên tố 16-bit trên SSE2/SSSE3
Có cách nào tốt hơn để transpose 8 thanh ghi SSE chứa Giá trị 16 bit so với thực hiện 24 unpck [lh] ps và 8/16 + shuffles và sử dụng 8 thanh ghi bổ sung? (Lưu ý sử dụng tối đa SSSE 3 hướng dẫn, Intel Merom, aka thiếu BLEND * từ SSE4.)
Giả sử bạn có thanh ghi v [0-7] và sử dụng t0-t7 làm thanh ghi aux. Trong giả intrinsics mã:
/* Phase 1: process lower parts of the registers */
/* Level 1: work first part of the vectors */
/* v[0] A0 A1 A2 A3 A4 A5 A6 A7
** v[1] B0 B1 B2 B3 B4 B5 B6 B7
** v[2] C0 C1 C2 C3 C4 C5 C6 C7
** v[3] D0 D1 D2 D3 D4 D5 D6 D7
** v[4] E0 E1 E2 E3 E4 E5 E6 E7
** v[5] F0 F1 F2 F3 F4 F5 F6 F7
** v[6] G0 G1 G2 G3 G4 G5 G6 G7
** v[7] H0 H1 H2 H3 H4 H5 H6 H7 */
t0 = unpcklps (v[0], v[1]); /* Extract first half interleaving */
t1 = unpcklps (v[2], v[3]); /* Extract first half interleaving */
t2 = unpcklps (v[4], v[5]); /* Extract first half interleaving */
t3 = unpcklps (v[6], v[7]); /* Extract first half interleaving */
t0 = pshufhw (t0, 0xD8); /* Flip middle 2 high */
t0 = pshuflw (t0, 0xD8); /* Flip middle 2 low */
t1 = pshufhw (t1, 0xD8); /* Flip middle 2 high */
t1 = pshuflw (t1, 0xD8); /* Flip middle 2 low */
t2 = pshufhw (t2, 0xD8); /* Flip middle 2 high */
t2 = pshuflw (t2, 0xD8); /* Flip middle 2 low */
t3 = pshufhw (t3, 0xD8); /* Flip middle 2 high */
t3 = pshuflw (t3, 0xD8); /* Flip middle 2 low */
/* t0 A0 B0 A1 B1 A2 B2 A3 B3 (A B - 0 1 2 3)
** t1 C0 D0 C1 D1 C2 D2 C3 D3 (C D - 0 1 2 3)
** t2 E0 F0 E1 F1 E2 F2 E3 F3 (E F - 0 1 2 3)
** t3 G0 H0 G1 H1 G2 H2 G3 H3 (G H - 0 1 2 3) */
/* L2 */
t4 = unpcklps (t0, t1);
t5 = unpcklps (t2, t3);
t6 = unpckhps (t0, t1);
t7 = unpckhps (t2, t3);
/* t4 A0 B0 C0 D0 A1 B1 C1 D1 (A B C D - 0 1)
** t5 E0 F0 G0 H0 E1 F1 G1 H1 (E F G H - 0 1)
** t6 A2 B2 C2 D2 A3 B3 C3 D3 (A B C D - 2 3)
** t7 E2 F2 G2 H2 E3 F3 G3 H3 (E F G H - 2 3) */
/* Phase 2: same with higher parts of the registers */
/* A A0 A1 A2 A3 A4 A5 A6 A7
** B B0 B1 B2 B3 B4 B5 B6 B7
** C C0 C1 C2 C3 C4 C5 C6 C7
** D D0 D1 D2 D3 D4 D5 D6 D7
** E E0 E1 E2 E3 E4 E5 E6 E7
** F F0 F1 F2 F3 F4 F5 F6 F7
** G G0 G1 G2 G3 G4 G5 G6 G7
** H H0 H1 H2 H3 H4 H5 H6 H7 */
t0 = unpckhps (v[0], v[1]);
t0 = pshufhw (t0, 0xD8); /* Flip middle 2 high */
t0 = pshuflw (t0, 0xD8); /* Flip middle 2 low */
t1 = unpckhps (v[2], v[3]);
t1 = pshufhw (t1, 0xD8); /* Flip middle 2 high */
t1 = pshuflw (t1, 0xD8); /* Flip middle 2 low */
t2 = unpckhps (v[4], v[5]);
t2 = pshufhw (t2, 0xD8); /* Flip middle 2 high */
t2 = pshuflw (t2, 0xD8); /* Flip middle 2 low */
t3 = unpckhps (v[6], v[7]);
t3 = pshufhw (t3, 0xD8); /* Flip middle 2 high */
t3 = pshuflw (t3, 0xD8); /* Flip middle 2 low */
/* t0 A4 B4 A5 B5 A6 B6 A7 B7 (A B - 4 5 6 7)
** t1 C4 D4 C5 D5 C6 D6 C7 D7 (C D - 4 5 6 7)
** t2 E4 F4 E5 F5 E6 F6 E7 F7 (E F - 4 5 6 7)
** t3 G4 H4 G5 H5 G6 H6 G7 H7 (G H - 4 5 6 7) */
/* Back to first part, v[0-3] can be re-written now */
/* L3 */
v[0] = unpcklpd (t4, t5);
v[1] = unpckhpd (t4, t5);
v[2] = unpcklpd (t6, t7);
v[3] = unpckhpd (t6, t7);
/* v[0] = A0 B0 C0 D0 E0 F0 G0 H0
** v[1] = A1 B1 C1 D1 E1 F1 G1 H1
** v[2] = A2 B2 C2 D2 E2 F2 G2 H2
** v[3] = A3 B3 C3 D3 E3 F3 G3 H3 */
/* Back to second part, t[4-7] can be re-written now... */
/* L2 */
t4 = unpcklps (t0, t1);
t5 = unpcklps (t2, t3);
t6 = unpckhps (t0, t1);
t7 = unpckhps (t2, t3);
/* t4 A4 B4 C4 D4 A5 B5 C5 D5 (A B C D - 4 5)
** t5 E4 F4 G4 H4 E5 F5 G5 H5 (E F G H - 4 5)
** t6 A6 B6 C6 D6 A7 B7 C7 D7 (A B C D - 6 7)
** t7 E6 F6 G6 H6 E7 F7 G7 H7 (E F G H - 6 7) */
/* L3 */
v[4] = unpcklpd (t4, t5);
v[5] = unpckhpd (t4, t5);
v[6] = unpcklpd (t6, t7);
v[7] = unpckhpd (t6, t7);
/* v[4] = A4 B4 C4 D4 E4 F4 G4 H4
** v[5] = A5 B5 C5 D5 E5 F5 G5 H5
** v[6] = A6 B6 C6 D6 E6 F6 G6 H6
** v[7] = A7 B7 C7 D7 E7 F7 G7 H7 */
Mỗi unpck * mất 3 chu kỳ của độ trễ, hoặc 2 cho thông lượng đối ứng (báo cáo của Agner.) Đây là tiêu diệt một phần lớn của tăng hiệu suất sử dụng SSE (trên mã này) vì đăng ký nhảy này mất gần một chu kỳ cho mỗi phần tử. Tôi đã cố gắng để hiểu tập tin asm x264 cho x86 transpose nhưng không hiểu các macro.
Cảm ơn!
Đẹp nhất, bạn đời! Bất kỳ cơ hội nào bạn có thể chỉ cho tôi theo một hướng nào đó để tìm thêm các biến đổi cơ bản với SSE? – alecco
@aleccolocco: không có nhiều tài liệu tốt về SSE ngoài kia, thật không may, ít nhất là cho các chủ đề nâng cao hơn. Tôi khuyên bạn nên xem các tài nguyên AltiVec (ví dụ: trên developer.apple.com) - rất nhiều kỹ thuật AltiVec dịch dễ dàng sang SSE. –
Tin vui: Tôi đã làm được. Tin xấu: chỉ có 5% đạt được hiệu suất trên 1 triệu yếu tố. Nhưng cảm ơn, tôi đã học được một số thủ thuật SSE thú vị! – alecco