Có vẻ như bạn muốn có một cách để đánh giá mã của FPU bị ràng buộc như thế nào, hoặc bạn đang sử dụng FPU hiệu quả như thế nào, thay vì đếm số lượng flop theo định nghĩa lỗi thời của "flop". Nói cách khác, bạn muốn một số liệu đạt đến cùng một đỉnh nếu mọi đơn vị điểm nổi đang chạy hết công suất mỗi chu kỳ. Chúng ta hãy nhìn vào Cầu Sandy của Intel để xem điều này có thể phát ra như thế nào.
Hoạt động điểm nổi hỗ trợ phần cứng
Con chip này hỗ trợ các hướng dẫn AVX , vì vậy các thanh ghi dài 32 byte (giữ 4 nhân đôi). Kiến trúc siêu khối cho phép các hướng dẫn trùng nhau, với hầu hết các hướng dẫn số học mất một vài chu kỳ để hoàn thành, mặc dù một hướng dẫn mới có thể có thể bắt đầu vào chu kỳ tiếp theo. Các ngữ nghĩa này thường được viết tắt bằng cách viết thông lượng độ trễ / nghịch đảo, giá trị 5/2 có nghĩa là hướng dẫn mất 5 chu kỳ để hoàn thành, nhưng bạn có thể bắt đầu một hướng dẫn mới mỗi chu kỳ khác (giả sử rằng các toán hạng có sẵn, do đó không có dữ liệu phụ thuộc và không chờ đợi bộ nhớ).
Có ba đơn vị số học dấu phẩy động trên mỗi lõi, nhưng thứ ba không liên quan đến cuộc thảo luận của chúng tôi, chúng tôi sẽ gọi hai đơn vị A và M có liên quan vì các hàm chính của chúng là phép cộng và phép nhân. Hướng dẫn ví dụ (xem bảng Agner Fog )
vaddpd
: bổ sung đóng gói, chiếm đơn vị A trong 1 chu kỳ, thông lượng trễ / nghịch đảo là 3/1
vmulpd
: phép nhân đóng gói, đơn vị M, 5/1
vmaxpd
: đóng gói chọn tối đa theo cặp, đơn vị A, 3/1
vdivpd
: phân chia đóng gói, đơn vị M (và một số A), 21/20 đến 45/44 tùy thuộc vào đầu vào
vsqrtpd
: đóng gói căn bậc hai, một số A và M, 21/21 đến 43/43 tùy thuộc vào đầu vào
vrsqrtps
: đóng gói căn bậc hai đối ứng có độ chính xác thấp cho đầu vào chính xác đơn (8 floats
)
Các ngữ nghĩa chính xác cho những gì có thể trùng lặp vdivpd
và vsqrtpd
rõ ràng là tinh tế và AFAIK, không được ghi lại ở bất cứ đâu. Trong hầu hết các cách sử dụng, tôi nghĩ rằng có rất ít khả năng cho sự chồng chéo, mặc dù từ ngữ trong hướng dẫn cho thấy rằng nhiều luồng có thể cung cấp nhiều khả năng hơn cho sự chồng chéo trong hướng dẫn này. Chúng ta có thể đạt được flops đỉnh nếu chúng ta bắt đầu một vaddpd
và vmulpd
trên mỗi chu kỳ, với tổng số 8 flops mỗi chu kỳ. Ma trận dày đặc ma trận nhân ( dgemm
) có thể có được gần hợp lý với đỉnh này.
Khi đếm flops cho các hướng dẫn đặc biệt, tôi sẽ xem xét số lượng FPU bị chiếm dụng. Giả sử đối số rằng trong phạm vi đầu vào của bạn, vdivpd
mất trung bình 24 chu kỳ để hoàn thành, chiếm hoàn toàn đơn vị M, nhưng việc bổ sung có thể (nếu có) được thực hiện đồng thời trong một nửa chu kỳ. FPU có khả năng thực hiện 24 bội số đóng gói và 24 bổ sung đóng gói trong các chu kỳ đó (xen kẽ hoàn hảo vaddpd
và vmulpd
), nhưng với một vdivpd
, điều tốt nhất chúng ta có thể làm là thêm 12 lần đóng gói bổ sung. Nếu chúng ta cho rằng cách tốt nhất có thể để phân chia là sử dụng phần cứng (hợp lý), chúng ta có thể tính vdivpd
là 36 "flops" được đóng gói, chỉ ra rằng chúng ta nên tính mỗi phép chia vô hướng là 36 "flops".
Với căn bậc hai đối ứng, đôi khi có thể đánh bại phần cứng, đặc biệt là nếu không cần độ chính xác đầy đủ hoặc nếu phạm vi đầu vào hẹp. Như đã đề cập ở trên, vrsqrtps
hướng dẫn rất rẻ tiền, vì vậy (nếu ở độ chính xác đơn), bạn có thể thực hiện một lần vrsqrtps
theo sau một hoặc hai lần lặp Newton để dọn dẹp. Những lần lặp Newton này chỉ là
y *= (3 - x*y*y)*0.5;
Nếu nhiều thao tác này cần được thực hiện, việc này có thể nhanh hơn đáng kể so với đánh giá ngây thơ y = 1/sqrt(x)
. Trước sự sẵn có của căn bậc hai gần đúng đối xứng phần cứng, một số mã nhạy cảm hiệu năng đã sử dụng các phép toán số nguyên khét tiếng để tìm dự đoán ban đầu cho phép lặp Newton.
Các hàm toán học do thư viện cung cấp
Chúng ta có thể áp dụng một heuristic tương tự cho các hàm toán học do thư viện cung cấp. Bạn có thể lập hồ sơ để xác định số lượng hướng dẫn SSE, nhưng như chúng ta đã thảo luận, đó không phải là toàn bộ câu chuyện và một chương trình dành toàn bộ thời gian để đánh giá các chức năng đặc biệt có thể không đạt đến đỉnh điểm, điều này có thể đúng, nhưng không phải là sự thật Sẽ hữu ích cho bạn biết rằng tất cả thời gian được dành ra khỏi tầm kiểm soát của bạn trên FPU.
Tôi đề nghị sử dụng một thư viện toán học vectơ tốt làm cơ sở (ví dụ VML của Intel, một phần của MKL). Đo số lượng chu kỳ cho mỗi cuộc gọi và nhân với số lần đạt cực đại có thể đạt được trên số chu kỳ đó. Vì vậy, nếu một số mũ đóng gói mất 50 chu kỳ để đánh giá, hãy tính nó bằng 100 lần nhân với chiều rộng của thanh ghi. Thật không may, các thư viện toán học vectơ đôi khi rất khó gọi và không có tất cả các hàm đặc biệt, vì vậy bạn có thể sẽ làm toán vô hướng, trong trường hợp đó bạn sẽ tính số mũ vô hướng giả định của chúng tôi là 100 flops (mặc dù có thể nó vẫn mất 50 theo chu kỳ, do đó bạn sẽ chỉ nhận được 25% "đỉnh" nếu dành toàn bộ thời gian để đánh giá các số mũ này).
Như những người khác đã đề cập, bạn có thể đếm chu kỳ và bộ đếm sự kiện phần cứng bằng PAPI hoặc các giao diện khác nhau. Để đếm chu kỳ đơn giản, bạn có thể đọc bộ đếm chu kỳ trực tiếp bằng cách sử dụng rdtsc
hướng dẫn với một đoạn lắp ráp nội tuyến.