首頁 > 後端開發 > C++ > 如何在現代 x86-64 Intel CPU 上實現每週期 4 次 FLOP?

如何在現代 x86-64 Intel CPU 上實現每週期 4 次 FLOP?

Susan Sarandon
發布: 2024-12-14 08:42:10
原創
146 人瀏覽過

How to Achieve 4 FLOPs Per Cycle on Modern x86-64 Intel CPUs?

如何達到每週期理論最高4次FLOP?

理論上可以實現4個浮點的峰值性能現代x86-64 Intel CPU 上每個週期的運算(雙精度),透過利用以下內容技巧:

最佳化SSE 指令碼

  • 使用SSE(流SIMD擴充)指令,可以並行處理多個資料元素。
  • 確保程式碼正確對齊以達到最佳 SSE效能。

循環展開與交錯

  • 展開內部循環以提高指令層級並行性。
  • 交錯乘法和加法利用CPU的管線技術

將運算分成三組

  • 將運算排列成三組

將運算按三組排列,以匹配某些Intel CPU 上的執行單元。這允許在 add 和 mul 指令之間交替,從而最大化吞吐量。

  • 避免不必要的停頓與依賴
最小化指令之間的資料依賴性以避免停頓.

使用編譯器最佳化(-O3或更高版本)來幫助識別和消除不必要的

範例程式碼
#include <emmintrin.h>
#include <omp.h>
#include <iostream>
using namespace std;

typedef unsigned long long uint64;

double test_dp_mac_SSE(double x, double y, uint64 iterations) {
    register __m128d r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, rA, rB, rC, rD, rE, rF;

    // Generate starting data.
    r0 = _mm_set1_pd(x);
    r1 = _mm_set1_pd(y);

    r8 = _mm_set1_pd(-0.0);

    r2 = _mm_xor_pd(r0, r8);
    r3 = _mm_or_pd(r0, r8);
    r4 = _mm_andnot_pd(r8, r0);
    r5 = _mm_mul_pd(r1, _mm_set1_pd(0.37796447300922722721));
    r6 = _mm_mul_pd(r1, _mm_set1_pd(0.24253562503633297352));
    r7 = _mm_mul_pd(r1, _mm_set1_pd(4.1231056256176605498));
    r8 = _mm_add_pd(r0, _mm_set1_pd(0.37796447300922722721));
    r9 = _mm_add_pd(r1, _mm_set1_pd(0.24253562503633297352));
    rA = _mm_sub_pd(r0, _mm_set1_pd(4.1231056256176605498));
    rB = _mm_sub_pd(r1, _mm_set1_pd(4.1231056256176605498));

    rC = _mm_set1_pd(1.4142135623730950488);
    rD = _mm_set1_pd(1.7320508075688772935);
    rE = _mm_set1_pd(0.57735026918962576451);
    rF = _mm_set1_pd(0.70710678118654752440);

    uint64 iMASK = 0x800fffffffffffffull;
    __m128d MASK = _mm_set1_pd(*(double*)&iMASK);
    __m128d vONE = _mm_set1_pd(1.0);

    uint64 c = 0;
    while (c < iterations) {
        size_t i = 0;
        while (i < 1000) {
            // Main computational loop

            r0 = _mm_mul_pd(r0, rC);
            r1 = _mm_add_pd(r1, rD);
            r2 = _mm_mul_pd(r2, rE);
            r3 = _mm_sub_pd(r3, rF);
            r4 = _mm_mul_pd(r4, rC);
            r5 = _mm_add_pd(r5, rD);
            r6 = _mm_mul_pd(r6, rE);
            r7 = _mm_sub_pd(r7, rF);
            r8 = _mm_mul_pd(r8, rC);
            r9 = _mm_add_pd(r9, rD);
            rA = _mm_mul_pd(rA, rE);
            rB = _mm_sub_pd(rB, rF);

            r0 = _mm_add_pd(r0, rF);
            r1 = _mm_mul_pd(r1, rE);
            r2 = _mm_sub_pd(r2, rD);
            r3 = _mm_mul_pd(r3, rC);
            r4 = _mm_add_pd(r4, rF);
            r5 = _mm_mul_pd(r5, rE);
            r6 = _mm_sub_pd(r6, rD);
            r7 = _mm_mul_pd(r7, rC);
            r8 = _mm_add_pd(r8, rF);
            r9 = _mm_mul_pd(r9, rE);
            rA = _mm_sub_pd(rA, rD);
            rB = _mm_mul_pd(rB, rC);

            r0 = _mm_mul_pd(r0, rC);
            r1 = _mm_add_pd(r1, rD);
            r2 = _mm_mul_pd(r2, rE);
            r3 = _mm_sub_pd(r3, rF);
            r4 = _mm_mul_pd(r4, rC);
            r5 = _mm_add_pd(r5, rD);
            r6 = _mm_mul_pd(r6, rE);
            r7 = _mm_sub_pd(r7, rF);
            r8 = _mm_mul_pd(r8, rC);
            r9 = _mm_add_pd(r9, rD);
登入後複製
以下程式碼片段示範如何在Intel Core i5 和Core i7 CPU上實現接近峰值性能:

以上是如何在現代 x86-64 Intel CPU 上實現每週期 4 次 FLOP?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板