Tôi đã có một số mã 32bit đơn giản tính toán sản phẩm của một mảng các số nguyên 32 bit. Vòng lặp bên trong trông như thế này:Tại sao chuyến đi khứ hồi của bộ nhớ nhanh hơn không thực hiện chuyến đi khứ hồi?
@@loop:
mov esi,[ebx]
mov [esp],esi
imul eax,[esp]
add ebx, 4
dec edx
jnz @@loop
Những gì tôi đang cố gắng để hiểu là tại sao đoạn code trên là nhanh hơn so với hai phiên bản của mã này, mà không thực hiện việc dư thừa bộ nhớ khứ hồi 6%:
@@loop:
mov esi,[ebx]
imul eax,esi
add ebx, 4
dec edx
jnz @@loop
và
@@loop:
imul eax,[ebx]
add ebx, 4
dec edx
jnz @@loop
hai mảnh thứ hai của mã thực thi trong hầu như cùng một lúc, và như đã đề cập cả hai đều chậm hơn so với phần đầu tiên (165ms 155ms vs, 200 triệu phần tử) 6%.
Tôi đã thử căn chỉnh mục tiêu nhảy theo cách thủ công thành ranh giới 16 byte, nhưng nó không có sự khác biệt.
Tôi đang chạy tính năng này trên Intel i7 4770k, Windows 10 x64.
Lưu ý: Tôi biết mã có thể được cải thiện bằng cách thực hiện tất cả các loại tối ưu hóa, tuy nhiên, tôi chỉ quan tâm đến hiệu suất khác biệt giữa các đoạn mã trên.
Tôi không thể cung cấp cho bạn tài liệu tham khảo (vì chúng có thể không tồn tại, vì chúng tiết lộ bí mật thương mại), nhưng có thể bạn đang thấy một nỗ lực phi thường mà Intel đưa vào hiệu suất bộ nhớ cache L1. – Gene
Điều này vẫn xảy ra khi bạn chèn một tải giả 'mov ecx, [ebx]' vào phiên bản thứ hai? – harold
Hiệu suất trong trường hợp được lưu trong bộ nhớ cache như thế nào? Vòng lặp đầu tiên sẽ phát hành bộ đệm vòng lặp tại một trong hai chu kỳ (vì nó là 5 uops-fop-domain uops trên CPU Haswell của bạn). Hai loại kia có thể phát hành tại một chu kỳ mỗi lần lặp. Tuy nhiên, chuỗi phụ thuộc 'vòng lặp' phụ thuộc vòng lặp nên hạn chế tất cả 3 chu trình trên mỗi lần lặp.Việc đầu tiên không có các cửa hàng và tải lại trong chuỗi phụ thuộc đường dẫn quan trọng, và Haswell có thể thực hiện 2x tải + 1x lưu trữ mỗi chu kỳ. (Pre-Haswell không có một cửa hàng chuyên dụng AGU). Tôi không thể thấy tại sao nó nhanh hơn, nhưng nó có nghĩa là nó không chậm hơn. –