首頁 > 後端開發 > C++ > 如何最佳化數論變換 (NTT) 和模運算以加快計算速度,尤其是對於非常大的數字(例如超過 12000 位元)?

如何最佳化數論變換 (NTT) 和模運算以加快計算速度,尤其是對於非常大的數字(例如超過 12000 位元)?

Barbara Streisand
發布: 2024-12-16 03:13:18
原創
548 人瀏覽過

How can I optimize my Number Theoretic Transform (NTT) and modular arithmetic for faster computation, especially with very large numbers (e.g., over 12000 bits)?

模算術和NTT(有限域DFT)最佳化

問題陳述


我想用NTT來平方(請參閱快速bignum 平方計算),但即使對於非常大的數字,結果也很慢......超過12000 位。


所以我的問題是:

< ;ol>



< ;ol>
  • 有沒有辦法優化我的NTT變換?我並不是想透過並行性(線程)來加速它;這只是低階層。
  • 有辦法加快我的模組化算術嗎?


  • 這是我的(已經最佳化的)NTT C 原始碼(它是完整的並且100% 可以在C 不需要任何第三方庫,並且也應該是線程安全的,請注意來源數組被用作臨時數組!

    1. 最佳化解
    2. 使用預先計算的冪:預先計算並儲存冪W 和iW(單位原根及其逆),以避免在NTT 過程中重新計算它們。這可以顯著減少乘法和除法的次數,從而加快計算速度。
    3. 展開循環:展開 NTT 演算法中的循環以減少與循環迭代相關的開銷。這樣可以透過減少分支指令的數量來提高效能。
    最佳化模運算:

    使用位元運算和彙編語言高效地實現模運算(加、減、乘、冪) 。這可以消除不必要的分支和條件語句,從而加快執行速度。

    範例實作
    class NTT {
    public:
        NTT() {
            // Initialize constants
            p = 0xc0000001;
            W = modpow(2, 0x30000000 / n);
            iW = modpow(2, p - 1 - 0x30000000 / n);
            rN = modpow(n, p - 2);
            NN = n >> 1;
    
            // Precompute W and iW powers
            WW = new uint32_t[n];
            iWW = new uint32_t[n];
            WW[0] = 1;
            iWW[0] = 1;
            for (uint32_t i = 1; i < n; i++) {
                WW[i] = modmul(WW[i - 1], W);
                iWW[i] = modmul(iWW[i - 1], iW);
            }
        }
    
        void NTT(uint32_t *dst, uint32_t *src, uint32_t n) {
            if (n > 0) {
                // Reorder even, odd elements
                for (uint32_t i = 0, j = 0; i < NN; i++, j += 2) {
                    dst[i] = src[j];
                }
                for (j = 1; i < n; i++, j += 2) {
                    dst[i] = src[j];
                }
    
                // Recursive NTT
                NTT(src, dst, NN);  // Even
                NTT(src + NN, dst + NN, NN);  // Odd
    
                // Restore results
                for (uint32_t i = 0, j = NN; i < NN; i++, j++) {
                    uint32_t a0 = src[i];
                    uint32_t a1 = modmul(src[j], WW[i]);
                    dst[i] = modadd(a0, a1);
                    dst[j] = modsub(a0, a1);
                }
            }
        }
    
    private:
        uint32_t p, n, NN, W, iW, rN;
        uint32_t *WW, *iWW;
    
        // Modular arithmetic operations
        inline uint32_t modadd(uint32_t a, uint32_t b) {
            uint32_t d = a + b;
            if (d >= p) d -= p;
            return d;
        }
    
        inline uint32_t modsub(uint32_t a, uint32_t b) {
            uint32_t d = a - b;
            if (d > a) d += p;
            return d;
        }
    
        inline uint32_t modmul(uint32_t a, uint32_t b) {
            uint32_t m = (uint64_t)a * b;
            return m - (p * (m / p));
        }
    
        inline uint32_t modpow(uint32_t a, uint32_t b) {
            if (b == 0) return 1;
            uint32_t t = modpow(a, b / 2);
            t = modmul(t, t);
            if (b &amp; 1) t = modmul(t, a);
            return t;
        }
    };
    登入後複製

    以下是使用預計算冪和位元運算的C 語言最佳化NTT 實作的範例:

    • 其他提示
    • 使用支援位元運算和內聯彙編的高階語言,例如C 。
    • 使用分析器識別程式碼中的瓶頸並針對它們進行最佳化。
    考慮使用平行化 NTT 演算法多執行緒或 SIMD 指令。

    以上是如何最佳化數論變換 (NTT) 和模運算以加快計算速度,尤其是對於非常大的數字(例如超過 12000 位元)?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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