คำนวณจำนวนการรันสูงสุดที่เป็นไปได้สำหรับสตริงที่มีขนาดใหญ่ที่สุด


24

[คำถามนี้เป็นการติดตามการคำนวณการวิ่งของสตริง ]

ช่วงเวลาpของสตริงwคือจำนวนเต็มบวกใด ๆpเช่นว่าw[i]=w[i+p] เมื่อใดก็ตามที่ทั้งสองด้านของสมการนี้ถูกกำหนด อนุญาตแสดงขนาดของระยะเวลาที่เล็กที่สุดของper(w) wเราบอกว่าสตริงwเป็น per(w) <= |w|/2IFF

ดังนั้นอย่างไม่เป็นทางการสตริงธาตุเป็นเพียงสตริงที่ทำขึ้นจากสตริงอื่นทำซ้ำอย่างน้อยหนึ่งครั้ง ภาวะแทรกซ้อนเพียงอย่างเดียวคือในตอนท้ายของสตริงเราไม่ต้องการสำเนาเต็มของสตริงซ้ำตราบใดที่มันถูกทำซ้ำอย่างครบถ้วนอย่างน้อยหนึ่งครั้ง

x = abcabสำหรับตัวอย่างพิจารณาสตริง per(abcab) = 3เป็นx[1] = x[1+3] = a, x[2]=x[2+3] = bและไม่มีระยะเวลาที่มีขนาดเล็ก สตริงabcabจึงไม่เป็นระยะ อย่างไรก็ตามสตริงababaเป็นระยะ ๆ per(ababa) = 2เป็น

ในฐานะที่เป็นตัวอย่างเพิ่มเติมabcabca, ababababaและabcabcabcนอกจากนี้ยังมีเป็นระยะ ๆ

สำหรับผู้ที่ชอบ regexes คนนี้ตรวจพบว่าสตริงเป็นระยะหรือไม่:

\b(\w*)(\w+\1)\2+\b

ภารกิจคือค้นหาสตริงย่อยตามระยะเวลาสูงสุดทั้งหมดในสตริงที่ยาวกว่า บางครั้งเรียกว่าการวิ่งในวรรณกรรม

สตริงย่อยwเป็นระยะย่อยสูงสุด (วิ่ง) ถ้ามันเป็นระยะเวลาและค่ามิได้w[i-1] = w[i-1+p] w[j+1] = w[j+1-p]อย่างไม่เป็นทางการ "รัน" ไม่สามารถอยู่ใน "รัน" ที่ใหญ่กว่าด้วยช่วงเวลาเดียวกัน

เนื่องจากการวิ่งสองครั้งสามารถแสดงสายอักขระเดียวกันที่เกิดขึ้นในสถานที่ที่แตกต่างกันในสายอักขระโดยรวมเราจะแสดงการวิ่งตามช่วงเวลา นี่คือคำจำกัดความข้างต้นซ้ำในแง่ของช่วงเวลา

สตริงย่อยการเรียกใช้ (หรือสตริงย่อยสูงสุด) ในสตริงTคือช่วงเวลา [i...j]ด้วยj>=iเช่นนั้น

  • T[i...j] เป็นคำที่มีคาบตามระยะเวลา p = per(T[i...j])
  • มันเป็นสูงสุด อย่างเป็นทางการค่ามิได้T[i-1] = T[i-1+p] T[j+1] = T[j+1-p]อย่างไม่เป็นทางการไม่สามารถอยู่ในการรันที่ใหญ่ขึ้นในช่วงเวลาเดียวกัน

แสดงว่าโดยชุดของการทำงานในสตริงRUNS(T)T

ตัวอย่างการวิ่ง

  • สี่สตริงระยะสูงสุด (วิ่ง) ในสตริงT = atattattมีT[4,5] = tt, T[7,8] = tt, ,T[1,4] = atatT[2,8] = tattatt

  • สตริงT = aabaabaaaacaacacมีดังต่อไปนี้ 7 สตริงระยะสูงสุด (วิ่ง): T[1,2] = aa, T[4,5] = aa, T[7,10] = aaaa, T[12,13] = aa, T[13,16] = acac, ,T[1,8] = aabaabaaT[9,15] = aacaaca

  • สตริงT = atatbatatbมีการรันสามรายการต่อไปนี้ พวกเขาคือ T[1, 4] = atat, และT[6, 9] = atat T[1, 10] = atatbatatb

ที่นี่ฉันใช้การจัดทำดัชนี 1 ครั้ง

งาน

เขียนโค้ดเพื่อให้สำหรับแต่ละจำนวนเต็ม n เริ่มต้นที่ 2 คุณส่งออกตัวเลขที่ใหญ่ที่สุดของการทำงานที่อยู่ในสตริงไบนารีใด ๆ nของความยาว

คะแนน

คะแนนของคุณนั้นสูงที่สุดที่nคุณไปถึงใน 120 วินาทีซึ่งสำหรับทุกคนk <= nไม่มีใครโพสต์คำตอบที่ถูกต้องสูงกว่าคุณ เห็นได้ชัดว่าถ้าคุณมีคำตอบที่ดีที่สุดแล้วคุณจะได้รับคะแนนสูงสุดสำหรับการnโพสต์ อย่างไรก็ตามแม้ว่าคำตอบของคุณจะไม่เหมาะสมคุณก็ยังสามารถได้คะแนนถ้าไม่มีใครสามารถเอาชนะได้

ภาษาและห้องสมุด

คุณสามารถใช้ภาษาและไลบรารี่ที่คุณต้องการได้ หากเป็นไปได้จะเป็นการดีที่จะสามารถเรียกใช้รหัสของคุณได้ดังนั้นโปรดระบุคำอธิบายโดยละเอียดเกี่ยวกับวิธีเรียกใช้ / รวบรวมรหัสของคุณใน Linux หากเป็นไปได้

ตัวอย่าง optima

ในสิ่งต่อไปนี้: n, optimum number of runs, example string.

2 1 00
3 1 000
4 2 0011
5 2 00011
6 3 001001
7 4 0010011
8 5 00110011
9 5 000110011
10 6 0010011001
11 7 00100110011
12 8 001001100100
13 8 0001001100100
14 10 00100110010011
15 10 000100110010011
16 11 0010011001001100
17 12 00100101101001011
18 13 001001100100110011
19 14 0010011001001100100
20 15 00101001011010010100
21 15 000101001011010010100
22 16 0010010100101101001011

รหัสของฉันควรออกอะไร

สำหรับแต่ละnรหัสของคุณควรส่งออกสายเดียวและจำนวนของการทำงานมันมี

My Machineเวลาของฉันจะทำงานบนเครื่องของฉัน นี่คือการติดตั้ง Ubuntu มาตรฐานบนโปรเซสเซอร์ AMD FX-8350 Eight-Core นี่ก็หมายความว่าฉันต้องสามารถเรียกใช้รหัสของคุณได้

คำตอบชั้นนำ

  • 49โดย Anders Kaseorg ในC เธรดเดี่ยวและเรียกใช้ด้วย L = 12 (RAM 2GB)
  • 27โดย cdlane ในC


1
หากคุณต้องการให้เราพิจารณาเฉพาะ{0,1}สตริงเท่านั้นโปรดระบุอย่างชัดเจนว่า มิฉะนั้นตัวอักษรอาจไม่มีที่สิ้นสุดและฉันไม่เห็นว่าทำไมการทดสอบของคุณควรดีที่สุดเพราะดูเหมือนว่าคุณจะค้นหาเฉพาะ{0,1}สตริงด้วย
ข้อบกพร่อง

3
@ flawr ฉันค้นหาสตริงเหนือตัวอักษรประกอบnไปด้วย12และมันไม่เคยเอาชนะตัวอักษรไบนารี แบบคาดเดายากฉันคาดหวังว่าไบนารีสตริงควรเหมาะสมที่สุดเนื่องจากการเพิ่มอักขระเพิ่มความยาวขั้นต่ำของการรัน
Peter Taylor

1
ในผลลัพธ์ที่ดีที่สุดข้างต้นคุณมี "12 7 001001010010" แต่โค้ดของฉันปั๊มออกมา "12 8 110110011011" โดยที่ระยะเวลา 1 การวิ่งคือ (11, 11, 00, 11, 11), ระยะเวลา 3 วิ่งคือ (110110, 011011) และมี รอบระยะเวลา 4 รัน (01100110) - ฉันจะไปไหนผิดในการนับระยะ
cdlane

1
@cdlane 0000 มีหนึ่งการทำงาน พิจารณาช่วงเวลาของ 000 ... มันเป็น 1 เสมอไม่ว่าจะมีกี่ศูนย์

คำตอบ:


9

C

นี่เป็นการค้นหาแบบเรียกซ้ำเพื่อหาคำตอบที่ดีที่สุดซึ่งจะถูกตัดอย่างหนักโดยใช้ขอบเขตบนของจำนวนการรันที่สามารถทำได้โดยส่วนที่เหลือที่ไม่รู้จักของสตริง การคำนวณขอบเขตบนใช้ตารางการค้นหาขนาดมหึมาซึ่งขนาดจะถูกควบคุมโดยค่าคงที่L( L=11: 0.5 GiB,: L=122 GiB,: L=138 GiB)

บนแล็ปท็อปของฉันสิ่งนี้จะเพิ่มขึ้นถึงn = 50 ใน 100 วินาที บรรทัดถัดไปมาที่ 142 วินาที

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#define N (8*sizeof(unsigned long long))
#define L 13
static bool a[N], best_a[N];
static int start[N/2 + 1], best_runs;
static uint8_t end_runs[2 << 2*L][2], small[N + 1][2 << 2*L];

static inline unsigned next_state(unsigned state, int b)
{
    state *= 2;
    state += b;
    if (state >= 2 << 2*L) {
        state &= ~(2 << 2*L);
        state |= 1 << 2*L;
    }
    return state;
}

static void search(int n, int i, int runs, unsigned state)
{
    if (i == n) {
        int r = runs;
        unsigned long long m = 0;
        for (int p = n / 2; p > 0; p--) {
            if (i - start[p] >= 2*p && !(m & 1ULL << start[p])) {
                m |= 1ULL << start[p];
                r++;
            }
        }
        if (r > best_runs) {
            best_runs = r;
            memcpy(best_a, a, n*sizeof(a[0]));
        }
    } else {
        a[i] = false;
        do {
            int r = runs, bound = 0, saved = 0, save_p[N/2], save_start[N/2], p, s = next_state(state, a[i]);
            unsigned long long m = 0;
            for (p = n/2; p > i; p--)
                if (p > L)
                    bound += (n - p + 1)/(p + 1);
            for (; p > 0; p--) {
                if (a[i] != a[i - p]) {
                    if (i - start[p] >= 2*p && !(m & 1ULL << start[p])) {
                        m |= 1ULL << start[p];
                        r++;
                    }
                    save_p[saved] = p;
                    save_start[saved] = start[p];
                    saved++;
                    start[p] = i + 1 - p;
                    if (p > L)
                        bound += (n - i)/(p + 1);
                } else {
                    if (p > L)
                        bound += (n - (start[p] + p - 1 > i - p ? start[p] + p - 1 : i - p))/(p + 1);
                }
            }
            bound += small[n - i - 1][s];

            if (r + bound > best_runs)
                search(n, i + 1, r, s);
            while (saved--)
                start[save_p[saved]] = save_start[saved];
        } while ((a[i] = !a[i]));
    }
}

int main()
{
    for (int n = 0; n <= N; n++) {
        if (n <= 2*L) {
            for (unsigned state = 1U << n; state < 2U << n; state++) {
                for (int b = 0; b < 2; b++) {
                    int r = 0;
                    unsigned long long m = 0;
                    for (int p = n / 2; p > 0; p--) {
                        if ((b ^ state >> (p - 1)) & 1) {
                            unsigned k = state ^ state >> p;
                            k &= -k;
                            k <<= p;
                            if (!(k & ~(~0U << n)))
                                k = 1U << n;
                            if (!((m | ~(~0U << 2*p)) & k)) {
                                m |= k;
                                r++;
                            }
                        }
                    }
                    end_runs[state][b] = r;
                }
                small[0][state] = end_runs[state][0] + end_runs[state][1];
            }
        }

        for (int l = 2*L < n - 1 ? 2*L : n - 1; l >= 0; l--) {
            for (unsigned state = 1U << l; state < 2U << l; state++) {
                int r0 = small[n - l - 1][next_state(state, 0)] + end_runs[state][0],
                    r1 = small[n - l - 1][next_state(state, 1)] + end_runs[state][1];
                small[n - l][state] = r0 > r1 ? r0 : r1;
            }
        }

        if (n >= 2) {
            search(n, 1, 0, 2U);
            printf("%d %d ", n, best_runs);
            for (int i = 0; i < n; i++)
                printf("%d", best_a[i]);
            printf("\n");
            fflush(stdout);
            best_runs--;
        }
    }
    return 0;
}

เอาท์พุท:

$ gcc -mcmodel=medium -O2 runs.c -o runs
$ ./runs
2 1 00
3 1 000
4 2 0011
5 2 00011
6 3 001001
7 4 0010011
8 5 00110011
9 5 000110011
10 6 0010011001
11 7 00100110011
12 8 001001100100
13 8 0001001100100
14 10 00100110010011
15 10 000100110010011
16 11 0010011001001100
17 12 00100101101001011
18 13 001001100100110011
19 14 0010011001001100100
20 15 00101001011010010100
21 15 000101001011010010100
22 16 0010010100101101001011
23 17 00100101001011010010100
24 18 001001100100110110011011
25 19 0010011001000100110010011
26 20 00101001011010010100101101
27 21 001001010010110100101001011
28 22 0010100101101001010010110100
29 23 00101001011010010100101101011
30 24 001011010010110101101001011010
31 25 0010100101101001010010110100101
32 26 00101001011010010100101101001011
33 27 001010010110100101001011010010100
34 27 0001010010110100101001011010010100
35 28 00100101001011010010100101101001011
36 29 001001010010110100101001011010010100
37 30 0010011001001100100010011001001100100
38 30 00010011001001100100010011001001100100
39 31 001001010010110100101001011010010100100
40 32 0010010100101101001010010110100101001011
41 33 00100110010001001100100110010001001100100
42 35 001010010110100101001011010110100101101011
43 35 0001010010110100101001011010110100101101011
44 36 00101001011001010010110100101001011010010100
45 37 001001010010110100101001011010110100101101011
46 38 0010100101101001010010110100101001011010010100
47 39 00101101001010010110100101101001010010110100101
48 40 001010010110100101001011010010110101101001011010
49 41 0010100101101001010010110100101101001010010110100
50 42 00101001011010010100101101001011010110100101101011
51 43 001010010110100101001011010110100101001011010010100

นี่คือทั้งหมดลำดับที่เหมาะสมที่สุดสำหรับn ≤ 64 (ไม่ได้เป็นเพียง lexicographically แรก) สร้างโดยเวอร์ชั่นล่าสุดของโปรแกรมนี้และหลายชั่วโมงของการคำนวณ

ลำดับที่เหมาะสมที่สุดที่น่าทึ่ง

คำนำหน้าของลำดับเศษส่วนอนันต์

1010010110100101001011010010110100101001011010010100101…

ที่ไม่แปรเปลี่ยนภายใต้การแปลง 101 ↦ 10100, 00 ↦ 101:

  101   00  101   101   00  101   00  101   101   00  101   101   00  …
= 10100 101 10100 10100 101 10100 101 10100 10100 101 10100 10100 101 …

ดูเหมือนจะมีจำนวนที่เหมาะสมเกือบมากของการวิ่ง - เสมอภายใน 2 ของที่ดีที่สุดสำหรับn ≤ 64 จำนวนของการทำงานในตัวอักษรแรกnหารด้วยnแนวทาง (13 - 5√5) / 2 ≈ 0.90983 แต่กลับกลายเป็นว่านี่ไม่ใช่อัตราส่วนที่เหมาะสม - ดูความคิดเห็น


ขอบคุณคำตอบและการแก้ไขของคุณ คุณคิดว่ากลุ่มเป้าหมายมีไว้สำหรับการแก้ปัญหาแบบไม่ใช้กำลังหรือไม่?

1
@ Lembik ฉันไม่รู้ ฉันคิดว่าวิธีแก้ปัญหาปัจจุบันของฉันค่อนข้างเร็วกว่า o (2 ^ N) ที่ให้หน่วยความจำเพียงพอ แต่ก็ยังคงเป็นเลขชี้กำลัง ฉันไม่พบสูตรโดยตรงที่ข้ามกระบวนการค้นหาทั้งหมด แต่อาจมีอยู่ ผมคาดเดาว่าลำดับ Thue-มอร์สเป็นasymptoticallyที่เหมาะสมกับN⋅5 / 6 - O (log N) วิ่ง แต่ดูเหมือนว่าจะอยู่ในกำมือของการทำงานหลังที่ดีที่สุดที่เกิดขึ้นจริง
Anders Kaseorg

ที่น่าสนใจ 42/50> 5/6

1
@ Lembik หนึ่งควรคาดหวังการคาดการณ์ asymptotic บางครั้งถูกตีด้วยจำนวนเล็กน้อย แต่ที่จริงฉันผิดอย่างสมบูรณ์ - ฉันพบลำดับที่ดีกว่ามากซึ่งดูเหมือนว่าจะเข้าใกล้N⋅ (13 - 5√5) / 2 ≈N⋅0.90983
Anders Kaseorg

ที่น่าประทับใจมาก. ฉันคิดว่าการคาดเดา 0.90983 ไม่ถูกต้อง ตรวจสอบbpaste.net/show/287821dc7214 มันมีความยาว 1,158 และมี 1,455 วิ่ง

2

เนื่องจากมันไม่ใช่การแข่งขันถ้ามีม้าเพียงตัวเดียวฉันจึงส่งวิธีแก้ปัญหาของฉันแม้ว่าจะเป็นเพียงเศษเสี้ยวของ Anders Kaseorg และเพียงหนึ่งในสามที่เป็นความลับ รวบรวมกับ:

gcc -O2 run-count.c -o run-count

หัวใจของอัลกอริทึมของฉันคือการเปลี่ยนแปลงอย่างง่ายและรูปแบบ XOR:

ป้อนคำอธิบายรูปภาพที่นี่

การทำงานของศูนย์ในผลลัพธ์ XOR ที่มากกว่าหรือเท่ากับงวดปัจจุบัน / กะบ่งชี้ว่าการทำงานในสายเดิมสำหรับรอบระยะเวลานี้ จากนี้คุณสามารถบอกได้ว่าระยะเวลาในการวิ่งนานแค่ไหนและมันเริ่มต้นและสิ้นสุดที่ไหน ส่วนที่เหลือของรหัสเป็นค่าใช้จ่ายการตั้งค่าสถานการณ์และถอดรหัสผลลัพธ์

ฉันหวังว่ามันจะใช้เวลาอย่างน้อย 28 นาทีหลังจากนั้นสองนาทีบนเครื่องของ Lembik (ฉันเขียนรุ่น pthread แต่จัดการเพื่อให้ทำงานช้าลง)

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>

enum { START = 0, WIDTH } ;

// Compare and shuffle just one thing while storing two
typedef union {
    uint16_t token;
    uint8_t data[sizeof(uint16_t)];
} overlay_t;

#define SENTINAL (0)  // marks the end of an array of overlay_t

#define NUMBER_OF_BITS (8 * sizeof(uint64_t))

void period_runs(uint64_t xor_bits, uint8_t nbits, uint8_t period, overlay_t *results) {

    overlay_t *results_ptr = results;
    uint8_t count = 0;

    for (uint8_t position = 0; position < nbits; position++) {

        if (xor_bits & 1ULL) {

            if ((nbits - position) < period) {
                break;  // no room left to succeed further
            }

            if (count >= period) {  // we found a run

                results_ptr->data[START] = position - (count - 1);
                results_ptr->data[WIDTH] = period + count;
                results_ptr++;
            }

            count = 0;
        } else {

            count++;
        }

        xor_bits >>= 1;
    }

    if (count >= period) {  // process the final run, if any

        results_ptr->data[START] = 0;
        results_ptr->data[WIDTH] = period + count;
        results_ptr++;
    }

    results_ptr->token = SENTINAL;
}

void number_runs(uint64_t number, uint8_t bit_length, overlay_t *results) {

    overlay_t sub_results[bit_length];
    uint8_t limit = bit_length / 2 + 1;
    uint64_t mask = (1ULL << (bit_length - 1)) - 1;

    overlay_t *results_ptr = results;
    results_ptr->token = SENTINAL;

    for (uint8_t period = 1; period < limit; period++) {

        uint64_t xor_bits = mask & (number ^ (number >> period));  // heart of the code
        period_runs(xor_bits, bit_length - period, period, sub_results);

        for (size_t i = 0; sub_results[i].token != SENTINAL; i++) {

            bool stop = false;  // combine previous and current results

            for (size_t j = 0; !stop && results[j].token != SENTINAL; j++) {

                // lower period result disqualifies higher period result over the same span 
                stop = (sub_results[i].token == results[j].token);
            }

            if (!stop) {

                (results_ptr++)->token = sub_results[i].token;
                results_ptr->token = SENTINAL;
            }
        }

        mask >>= 1;
    }
}

int main() {

    overlay_t results[NUMBER_OF_BITS];

    for (uint8_t bit_length = 2; bit_length < 25; bit_length++) {

        int best_results = -1;
        uint64_t best_number = 0;

        for (uint64_t number = 1ULL << (bit_length - 1); number < (1ULL << bit_length); number++) {

            // from the discussion comments, I should be able to solve this
            // with just bit strings that begin "11...", so toss the rest
            if ((number & (1ULL << (bit_length - 2))) == 0ULL) {

                continue;
            }

            uint64_t reversed = 0;

            for (uint8_t i = 0; i < bit_length; i++) {

                if (number & (1ULL << i)) {

                    reversed |= (1ULL << ((bit_length - 1) - i));
                }
            }

            if (reversed > number) {

                continue;  // ~ 1/4 of bit_strings are simply reversals, toss 'em
            }

            number_runs(number, bit_length, results);
            overlay_t *results_ptr = results;
            int count = 0;

            while ((results_ptr++)->token != SENTINAL) {

                count++;
            }

            if (count > best_results) {

                best_results = count;
                best_number = number;
            }
        }

        char *best_string = malloc(bit_length + 1);
        uint64_t number = best_number;
        char *string_ptr = best_string;

        for (int i = bit_length - 1; i >= 0; i--) {

            *(string_ptr++) = (number & (1ULL << i)) ? '1' : '0';
        }

        *string_ptr = '\0';

        printf("%u %d %s\n", bit_length, best_results, best_string);

        free(best_string);
    }

    return 0;
}

เอาท์พุท:

> gcc -O2 run-count.c -o run-count
> ./run-count
2 1 11
3 1 110
4 2 1100
5 2 11000
6 3 110011
7 4 1100100
8 5 11001100
9 5 110010011
10 6 1100110011
11 7 11001100100
12 8 110110011011
13 8 1100100010011
14 10 11001001100100
15 10 110010011001000
16 11 1100100110010011
17 12 11001100100110011
18 13 110011001001100100
19 14 1101001011010010100
20 15 11010110100101101011
21 15 110010011001001100100
22 16 1100101001011010010100
23 17 11010010110100101001011
24 18 110100101001011010010100
25 19 1100100110010001001100100
26 20 11010010100101101001010010
27 21 110010011001000100110010011
28 22 1101001010010110100101001011

ยินดีต้อนรับม้าที่สอง! คำถามเล็ก ๆ ทำไมคุณและคำตอบอื่น ๆ แนะนำให้ -O2 แทน -O3

@ Lembik ด้วยการเพิ่มประสิทธิภาพ -O2 ฉันสามารถวัดความแตกต่างของเวลาในการเรียกใช้โค้ด แต่ฉันไม่สามารถวัดเพิ่มเติมได้ด้วย -O3 เนื่องจากเราคาดคะเนว่าจะปิดการซื้อขายอย่างปลอดภัยเพื่อความเร็วฉันคิดว่าระดับสูงสุดที่สร้างความแตกต่างได้ดีที่สุด หากคุณเชื่อว่ารหัสของฉันจะอยู่ในอันดับที่สูงกว่าด้วย -O3 ไปเลย!
cdlane

-O3ไม่ได้ตั้งใจจะ "ไม่ปลอดภัย" มันเปิดใช้งานการทำให้เป็นเวกเตอร์อัตโนมัติ แต่อาจไม่มีอะไรที่จะทำให้เวกเตอร์ที่นี่ บางครั้งมันอาจทำให้โค้ดช้าลงเช่นถ้าใช้ CMov ไร้สาขาสำหรับสิ่งที่สาขาคาดเดาได้เป็นอย่างดี แต่มักจะช่วยได้ มันมักจะคุ้มค่าลองเสียงดังกราวเช่นกันเพื่อดูว่าของ gcc หรือเสียงดังกราวทำรหัสที่ดีกว่าสำหรับวงเฉพาะ นอกจากนี้ยังช่วยในการใช้งาน-march=nativeหรืออย่างน้อย-mtune=nativeถ้าคุณยังต้องการไบนารีที่ทำงานได้ทุกที่
Peter Cordes
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.