Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用gcc进行-mavx优化失败?_C_Gcc_Mingw_Avx - Fatal编程技术网

使用gcc进行-mavx优化失败?

使用gcc进行-mavx优化失败?,c,gcc,mingw,avx,C,Gcc,Mingw,Avx,编辑下面的部分解决方案(编辑2),但我还有一个问题(见末尾) 我正在尝试编译下面的C程序,在Windows7上,32位,在a上运行(根据Windows系统信息)。如果我理解正确的话,这个处理器没有AVX扩展,所以发生一些事情是很自然的,我只是不确定到底是什么。最初,我在使用gcc进行优化,我尝试了-mavx,这是“偶然的” 下面的程序计算数字0的排列。。。n-1(以n为参数),以及每个排列的秩(其在该顺序中的位置)和“unrank”(从秩恢复排列),并检查所有这些是否正确。最后只打印“确定”或“

编辑下面的部分解决方案(编辑2),但我还有一个问题(见末尾)

我正在尝试编译下面的C程序,在Windows7上,32位,在a上运行(根据Windows系统信息)。如果我理解正确的话,这个处理器没有AVX扩展,所以发生一些事情是很自然的,我只是不确定到底是什么。最初,我在使用gcc进行优化,我尝试了-mavx,这是“偶然的”

下面的程序计算数字0的排列。。。n-1(以n为参数),以及每个排列的秩(其在该顺序中的位置)和“unrank”(从秩恢复排列),并检查所有这些是否正确。最后只打印“确定”或“错误”


  • 使用
    gcc-O3
    ,程序在我检查了所有整数输入的情况下正确运行(1“我不知道如何使它变短,同时仍然显示出这种奇怪的行为”--我建议将示例平分,与良好情况下的中间预期结果进行比较。@user3629249否,“I”的值有一次变为0(当最后一个排列被点击时:整个“a”都在减少)。由于“i”是在后面使用的,我不知道你怎么能想象循环什么都不做:它的唯一目的是找到“i”。可能是“for”后面的分号让你感到困扰。C允许这样做。@user3629249,你可能知道,
    for(a;b;C)d
    完全等同于
    a;而(b){d;c;}
    。for循环中可能缺少“a”、“b”、“c”中的任何一个,而“d”可能会被简化为一个分号。W.r.t.你的最后一个问题:简单。这将是令人愤怒的(而且很慢)在每个SSE/AVX指令之前进行运行时检查,以验证CPU是否支持其指令集。使用
    -mavx
    承诺二进制文件将仅在支持AVX的CPU上运行;如果不是这样,x86 CPU将引发异常
    #UD
    (未定义的操作码),操作系统通过向有罪进程提供
    SIGILL
    (非法指令)来作出反应信号,其默认操作是中止。@Iwillnotexistidnotexist实际上,它必须如此简单。快速检查显示,即使是除法0,或取消对空指针的引用,也会悄悄中止。我认为默认情况下会有消息,可能是因为我过去的Linux经验(我想他们会在Linux中打印消息?)实际上,不,'a'最后是数组{0,1,…n-1},因为当next_perm命中最后一个时(这是递减的),它在返回之前将其反转,因此“a”被重置为其初始状态。我的问题并不是像我所写的那样,程序真正做的是什么:
    next\u perm
    按字典顺序查找下一个排列。
    rank
    计算排列在所有排列列表中的位置,而
    unrank
    则相反(从其位置计算perm)由于有n个排列,并且程序枚举了所有排列,花费的时间甚至超过了指数增长。此外,正如我在问题中所解释的,我编写程序是为了测试3个函数
    next\u perm
    rank
    unrank
    是否正确地完成了它们的工作:它以字典或字典的形式计算所有排列der与next_perm一起,对于存储在“a”中的每一个,它计算它的位置,它必须是正确的位置(0,1,…n!-1),然后从这个位置计算回排列,它必须等于“a”。我在调用rank之前复制“a”,因为函数会破坏它的输入。举个例子(或字典顺序)这里的平均值。对于n=3,排列为011;021;1021;1201;2101;2110。其中有3!=6。
    #include <stdlib.h>
    #include <stdio.h>
    
    #define SWAP(a,b) {int c; c = a; a = b; b = c;}
    
    int next_perm(int n, int a[n]) {
        int i, j, k;
        for(i = n - 1; i > 0 && a[i - 1] > a[i]; i--);
        for(j = i, k = n - 1; j < k; j++, k--) SWAP(a[j], a[k]);
        if(i == 0) return 0;
        for(j = i--; a[j] < a[i]; j++);
        SWAP(a[i], a[j]);
        return 1;
    }
    
    #undef SWAP
    
    void copyvec(int n, int dst[n], int src[n]) {
        int i;
        for(i = 0; i < n; i++) {
            dst[i] = src[i];
        }
    }
    
    int eqvec(int n, int a[n], int b[n]) {
        int i;
        for(i = 0; i < n; i++) {
            if(a[i] != b[i]) return 0;
        }
        return 1;
    }
    
    int rank(int n, int a[n]) {
        int v[n], i, j, r;
        v[n - 1] = 1;
        for(j = n - 2; j >= 0; j--) v[j] = v[j + 1]*(n - 1 - j);
        for(r = i = 0; ; i++) {
            for(j = i; j < n; j++) {
                if(a[j] > j) goto cont;
    
            }
            return r;
    cont:
            i = j;
            r += v[i]*(a[i] - i);
            for(j = i + 1; j < n; j++) {
                if(a[j] < a[i]) a[j]++;
            }
        }
    }
    
    void unrank(int n, int a[n], int p) {
        int v[n], i, j, r, s;
        v[n - 1] = 1;
        for(i = n - 2; i >= 0; i--) v[i] = v[i + 1]*(n - 1 - i);
        p %= n*v[0];
        for(i = 0; i < n; i++) a[i] = i;
        for(i = 0; p > 0; i++) {
            for(; v[i] > p; i++);
            r = p/v[i];
            p %= v[i];
            for(s = a[j = i + r]; j >= i; j--) a[j] = a[j - 1];
            a[i] = s;
        }
    }
    
    int main(int argc, char **argv) {
        int n, i, r, s = 0, q = 0;
        int *a = NULL, *b = NULL, *c = NULL;
        if(argc == 2 && (n = strtol(argv[1], NULL, 0)) > 0) {
            a = malloc(n*sizeof(int));
            b = malloc(n*sizeof(int));
            c = malloc(n*sizeof(int));
            if(!a || !b || !c) {
                puts("Unable to allocate memory");
                goto end;
            } else {
                for(i = 0; i < n; i++) a[i] = i;
                do {
                    copyvec(n, b, a);
                    r = rank(n, b);
                    unrank(n, c, r);
                    q |= s++ != r || !eqvec(n, a, c);
                } while(next_perm(n, a));
                puts(q?"Error":"OK");
            }
        } else {
            puts("perm n - Check all permutations of {0 ... n - 1}, with n > 0");
        }
    end:
        if(a) free(a);
        if(b) free(b);
        if(c) free(c);
        return 0;
    }
    
    #include <stdlib.h>
    #include <stdio.h>
    
    #define SWAP(a,b) {int c; c = a; a = b; b = c;}
    
    int next_perm(int n, int a[n]) {
        int i, j, k;
        for(i = n - 1; i > 0 && a[i - 1] > a[i]; i--);
        for(j = i, k = n - 1; j < k; j++, k--) SWAP(a[j], a[k]);
        if(i == 0) return 0;
        for(j = i--; a[j] < a[i]; j++);
        SWAP(a[i], a[j]);
        return 1;
    }
    
    #undef SWAP
    
    int main(int argc, char **argv) {
        int n, i, r, s = 0, q = 0, a[20];
        n = strtol(argv[1], NULL, 0);
        for(i = 0; i < n; i++) a[i] = i;
        while(next_perm(n, a));
        puts(q?"Error":"OK");
        return 0;
    }
    
    _next_perm:
    LFB0:
        push    ebp
        push    edi
        push    esi
        push    ebx
        mov ecx, DWORD PTR [esp+20]
        mov edx, DWORD PTR [esp+24]
        lea eax, [ecx-1]
        test    eax, eax
        jle L12
        mov edi, DWORD PTR [edx-4+ecx*4]
        cmp DWORD PTR [edx-8+ecx*4], edi
        mov ecx, eax
        jg  L5
        jmp L11
    L28:
        mov esi, DWORD PTR [edx+ecx*4]
        cmp DWORD PTR [edx-4+ecx*4], esi
        jle L27
    L5:
        sub ecx, 1
        jne L28
    L4:
        mov ebx, ecx
    L7:
        mov esi, DWORD PTR [edx+ebx*4]
        mov edi, DWORD PTR [edx+eax*4]
        mov DWORD PTR [edx+ebx*4], edi
        mov DWORD PTR [edx+eax*4], esi
        add ebx, 1
        sub eax, 1
        cmp ebx, eax
        jl  L7
    L2:
        xor eax, eax
        test    ecx, ecx
        je  L23
    L11:
        sal ecx, 2
        lea esi, [edx+ecx]
        lea ebp, [edx-4+ecx]
        mov ebx, DWORD PTR [esi]
        mov edi, DWORD PTR [ebp+0]
        cmp edi, ebx
        jle L9
        lea eax, [edx+4+ecx]
    L10:
        mov esi, eax
        add eax, 4
        mov ebx, DWORD PTR [eax-4]
        cmp ebx, edi
        jl  L10
    L9:
        mov DWORD PTR [ebp+0], ebx
        mov eax, 1
        mov DWORD PTR [esi], edi
    L23:
        pop ebx
        pop esi
        pop edi
        pop ebp
        ret
    L27:
        cmp eax, ecx
        jg  L4
        jmp L11
    L12:
        mov ecx, eax
        jmp L2
    
    int main(int argc, char **argv) {
        int n, i, q = 0, a[20];
        puts("X");
        n = strtol(argv[1], NULL, 0);
        puts("Y");
        for(i = 0; i < n; i++) a[i] = i;
        puts("Z");
        while(next_perm(n, a));
        puts(q?"Error":"OK");
        return 0;
    }
    
    _main:
        push    ebp
        mov ebp, esp
        push    edi
        push    esi
        push    ebx
        and esp, -16
        sub esp, 96
        call    ___main
        mov DWORD PTR [esp], OFFSET FLAT:LC1
        call    _puts
        mov eax, DWORD PTR [ebp+12]
        mov DWORD PTR [esp+8], 0
        mov DWORD PTR [esp+4], 0
        mov eax, DWORD PTR [eax+4]
        mov DWORD PTR [esp], eax
        call    _strtol
        mov DWORD PTR [esp], OFFSET FLAT:LC2
        mov ebx, eax
        call    _puts
        test    ebx, ebx
        jle L17
        lea edx, [ebx-4]
        lea ecx, [ebx-1]
        shr edx, 2
        add edx, 1
        cmp ecx, 3
        lea eax, [0+edx*4]
        jbe L10
        vmovdqa xmm1, XMMWORD PTR LC4
        lea esi, [esp+16]
        xor ecx, ecx
        vmovdqa xmm0, XMMWORD PTR LC0
    L5:
        mov edi, ecx
        add ecx, 1
        sal edi, 4
        cmp edx, ecx
        vmovaps XMMWORD PTR [esi+edi], xmm0
        vpaddd  xmm0, xmm0, xmm1
        ja  L5
        cmp ebx, eax
        je  L9
    L4:
        lea edx, [eax+1]
        mov DWORD PTR [esp+16+eax*4], eax
        cmp ebx, edx
        jle L9
        mov DWORD PTR [esp+16+edx*4], edx
        lea edx, [eax+2]
        cmp ebx, edx
        jle L9
        add eax, 3
        mov DWORD PTR [esp+16+edx*4], edx
        cmp ebx, eax
        jle L9
        mov DWORD PTR [esp+16+eax*4], eax
    L9:
        mov DWORD PTR [esp], OFFSET FLAT:LC3
        call    _puts
    L3:
        mov DWORD PTR [esp+4], esi
        mov DWORD PTR [esp], ebx
        call    _next_perm
        test    eax, eax
        jne L3
        mov DWORD PTR [esp], OFFSET FLAT:LC5
        call    _puts
        lea esp, [ebp-12]
        xor eax, eax
        pop ebx
        pop esi
        pop edi
        pop ebp
        ret
    L10:
        xor eax, eax
        lea esi, [esp+16]
        jmp L4
    L17:
        lea esi, [esp+16]
        jmp L9
    
    This code always results in:
    where parameter = n
    a[] = {0,0,2, 3, ...,n-2,n-1}
    b[] = {n-1, n-1, ... , n-1}
    c[] = {n-1, n-2, ... , 0}
    when it reaches the above conditions,
    then it exits with "OK"
    
    the amount of time spent executing the code 
    climbs at an exponential rate
    as the value of the parameter is increased