Đương nhiên nó sẽ phụ thuộc rất nhiều vào mã của bạn, nhưng tôi đã triển khai hai hàm đơn giản bằng cả hai cách tiếp cận. See code
__m128 calc_set1(float num1, float num2)
{
__m128 num1_4 = _mm_set1_ps(num1);
__m128 num2_4 = _mm_set1_ps(num2);
__m128 result4 = _mm_mul_ps(num1_4, num2_4);
return result4;
}
__m128 calc_mov(float* num1_4_addr, float* num2_4_addr)
{
__m128 num1_4 = _mm_load_ps(num1_4_addr);
__m128 num2_4 = _mm_load_ps(num2_4_addr);
__m128 result4 = _mm_mul_ps(num1_4, num2_4);
return result4;
}
và lắp ráp
calc_set1(float, float):
shufps $0, %xmm0, %xmm0
shufps $0, %xmm1, %xmm1
mulps %xmm1, %xmm0
ret
calc_mov(float*, float*):
movaps (%rdi), %xmm0
mulps (%rsi), %xmm0
ret
Bạn có thể thấy rằng calc_mov()
không như những gì bạn mong muốn và calc_set1()
sử dụng một hướng dẫn ngẫu nhiên duy nhất.
Hướng dẫn movps
có thể mất khoảng bốn chu kỳ để tạo địa chỉ + hơn nếu cổng tải của bộ nhớ cache L1 bận + hơn trong trường hợp hiếm hoi của bộ nhớ cache bị thiếu.
shufps
sẽ thực hiện một chu kỳ đơn trên bất kỳ vi kiến trúc Intel gần đây nào. Tôi tin rằng điều này là đúng cho dù đó là cho SSE128 hoặc AVX256. Do đó, tôi khuyên bạn nên sử dụng phương pháp mm_set1_ps
.
Tất nhiên, lệnh phát ngẫu nhiên giả định phao đã có trong thanh ghi SSE/AVX. Trong trường hợp bạn đang tải nó từ bộ nhớ, sau đó phát sóng sẽ tốt hơn vì nó sẽ chụp tốt nhất của movps
và shufps
trong một hướng dẫn duy nhất.
Khi bạn nói "tải" tôi giả sử bạn có nghĩa là bằng cách sao chép biến hiện có (đăng ký), phải không? Không phải từ bộ nhớ? – Mehrdad
@Mehrdad Vâng, chủ yếu là tôi có ý nghĩa từ bộ nhớ, trừ khi nó xảy ra trong sổ đăng ký rồi. Đối với tùy chọn tiền lọc, ý tôi là đặt __m128 ở đâu đó trong mã của bạn, và sau đó tham khảo nó bất cứ nơi nào bạn cần, thay vì tạo cùng một véc tơ với _mm_set1_ps. Đó là giải thích đơn giản nhất. – Thomas
Thật khó để nói hoàn toàn vì 'mm_set1_ps' không tương ứng với bất kỳ lệnh nào. Nó thậm chí có thể dịch những gì bạn đang đề xuất làm. Tại sao không kiểm tra lắp ráp và xem? Ngoài ra, vì bạn đã gắn thẻ bài đăng của mình với AVX, bạn có thể muốn biết có nội tại mới hơn tương ứng với một hướng dẫn duy nhất: '_mm_broadcast_ss' – hayesti