doutan2228 2016-09-15 02:29
浏览 47
已采纳

为什么汇编POPCNTQ基准测试比使用整数技巧的本机Go函数要慢?

ASM version

TEXT ·CountBitsUint64PopCnt(SB),NOSPLIT,$0
    POPCNTQ    x+0(FP), AX
    MOVQ       AX, ret+8(FP)
    RET

Go Version

const (
    m1q uint64 = 0x5555555555555555
    m2q        = 0x3333333333333333
    m4q        = 0x0f0f0f0f0f0f0f0f
    hq         = 0x0101010101010101
)

func CountBitsUint64(x uint64) int {
    x -= (x >> 1) & m1q              // put count of each 2 bits into those 2 bits
    x = (x & m2q) + ((x >> 2) & m2q) // put count of each 4 bits into those 4 bits
    x = (x + (x >> 4)) & m4q         // put count of each 8 bits into those 8 bits
    return int((x * hq) >> 56)       // returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
}

Go Version (go tool compile -S popcount.go)

"".CountBitsUint64 t=1 size=101 args=0x10 locals=0x0
    0x0000 00000 (popcount.go:81)   TEXT    "".CountBitsUint64(SB), $0-16
    0x0000 00000 (popcount.go:81)   NOP
    0x0000 00000 (popcount.go:81)   NOP
    0x0000 00000 (popcount.go:81)   FUNCDATA    $0, gclocals·23e8278e2b69a3a75fa59b23c49ed6ad(SB)
    0x0000 00000 (popcount.go:81)   FUNCDATA    $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
    0x0000 00000 (popcount.go:82)   MOVQ    "".x+8(FP), AX
    0x0005 00005 (popcount.go:82)   MOVQ    AX, CX
    0x0008 00008 (popcount.go:82)   SHRQ    $1, AX
    0x000b 00011 (popcount.go:82)   MOVQ    $6148914691236517205, DX
    0x0015 00021 (popcount.go:82)   ANDQ    DX, AX
    0x0018 00024 (popcount.go:82)   SUBQ    AX, CX
    0x001b 00027 (popcount.go:83)   MOVQ    $3689348814741910323, AX
    0x0025 00037 (popcount.go:83)   MOVQ    CX, DX
    0x0028 00040 (popcount.go:83)   ANDQ    AX, CX
    0x002b 00043 (popcount.go:83)   SHRQ    $2, DX
    0x002f 00047 (popcount.go:83)   ANDQ    AX, DX
    0x0032 00050 (popcount.go:83)   LEAQ    (CX)(DX*1), AX
    0x0036 00054 (popcount.go:84)   MOVQ    AX, CX
    0x0039 00057 (popcount.go:84)   SHRQ    $4, AX
    0x003d 00061 (popcount.go:84)   ADDQ    CX, AX
    0x0040 00064 (popcount.go:84)   MOVQ    $1085102592571150095, CX
    0x004a 00074 (popcount.go:84)   ANDQ    CX, AX
    0x004d 00077 (popcount.go:85)   MOVQ    $72340172838076673, CX
    0x0057 00087 (popcount.go:85)   IMULQ   AX, CX
    0x005b 00091 (popcount.go:85)   SHRQ    $56, CX
    0x005f 00095 (popcount.go:85)   MOVQ    CX, "".~r1+16(FP)
    0x0064 00100 (popcount.go:85)   RET
    0x0000 48 8b 44 24 08 48 89 c1 48 d1 e8 48 ba 55 55 55  H.D$.H..H..H.UUU
    0x0010 55 55 55 55 55 48 21 d0 48 29 c1 48 b8 33 33 33  UUUUUH!.H).H.333
    0x0020 33 33 33 33 33 48 89 ca 48 21 c1 48 c1 ea 02 48  33333H..H!.H...H
    0x0030 21 c2 48 8d 04 11 48 89 c1 48 c1 e8 04 48 01 c8  !.H...H..H...H..
    0x0040 48 b9 0f 0f 0f 0f 0f 0f 0f 0f 48 21 c8 48 b9 01  H.........H!.H..
    0x0050 01 01 01 01 01 01 01 48 0f af c8 48 c1 e9 38 48  .......H...H..8H
    0x0060 89 4c 24 10 c3
"".CountBitsUint64Alt t=1 size=142 args=0x10 locals=0x0
    0x0000 00000 (popcount.go:88)   TEXT    "".CountBitsUint64Alt(SB), $0-16
    0x0000 00000 (popcount.go:88)   NOP
    0x0000 00000 (popcount.go:88)   NOP
    0x0000 00000 (popcount.go:88)   FUNCDATA    $0, gclocals·23e8278e2b69a3a75fa59b23c49ed6ad(SB)
    0x0000 00000 (popcount.go:88)   FUNCDATA    $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
    0x0000 00000 (popcount.go:89)   MOVQ    "".x+8(FP), AX
    0x0005 00005 (popcount.go:89)   MOVQ    AX, CX
    0x0008 00008 (popcount.go:89)   SHRQ    $32, AX
    0x000c 00012 (popcount.go:89)   MOVQ    AX, DX
    0x000f 00015 (popcount.go:89)   SHRL    $1, AX
    0x0011 00017 (popcount.go:89)   ANDL    $1431655765, AX
    0x0016 00022 (popcount.go:89)   SUBL    AX, DX
    0x0018 00024 (popcount.go:89)   MOVL    DX, AX
    0x001a 00026 (popcount.go:89)   ANDL    $858993459, DX
    0x0020 00032 (popcount.go:89)   SHRL    $2, AX
    0x0023 00035 (popcount.go:89)   ANDL    $858993459, AX
    0x0028 00040 (popcount.go:89)   ADDL    DX, AX
    0x002a 00042 (popcount.go:89)   MOVL    AX, DX
    0x002c 00044 (popcount.go:89)   SHRL    $4, AX
    0x002f 00047 (popcount.go:89)   ADDL    DX, AX
    0x0031 00049 (popcount.go:89)   ANDL    $252645135, AX
    0x0036 00054 (popcount.go:89)   MOVL    AX, DX
    0x0038 00056 (popcount.go:89)   SHRL    $8, AX
    0x003b 00059 (popcount.go:89)   ADDL    DX, AX
    0x003d 00061 (popcount.go:89)   MOVL    AX, DX
    0x003f 00063 (popcount.go:89)   SHRL    $16, AX
    0x0042 00066 (popcount.go:89)   ADDL    DX, AX
    0x0044 00068 (popcount.go:89)   MOVQ    CX, DX
    0x0047 00071 (popcount.go:89)   SHRL    $1, CX
    0x0049 00073 (popcount.go:89)   ANDL    $1431655765, CX
    0x004f 00079 (popcount.go:89)   SUBL    CX, DX
    0x0051 00081 (popcount.go:89)   MOVL    DX, CX
    0x0053 00083 (popcount.go:89)   ANDL    $858993459, DX
    0x0059 00089 (popcount.go:89)   SHRL    $2, CX
    0x005c 00092 (popcount.go:89)   ANDL    $858993459, CX
    0x0062 00098 (popcount.go:89)   ADDL    DX, CX
    0x0064 00100 (popcount.go:89)   MOVL    CX, DX
    0x0066 00102 (popcount.go:89)   SHRL    $4, CX
    0x0069 00105 (popcount.go:89)   ADDL    DX, CX
    0x006b 00107 (popcount.go:89)   ANDL    $252645135, CX
    0x0071 00113 (popcount.go:89)   MOVL    CX, DX
    0x0073 00115 (popcount.go:89)   SHRL    $8, CX
    0x0076 00118 (popcount.go:89)   ADDL    DX, CX
    0x0078 00120 (popcount.go:89)   MOVL    CX, DX
    0x007a 00122 (popcount.go:89)   SHRL    $16, CX
    0x007d 00125 (popcount.go:89)   ADDL    DX, CX
    0x007f 00127 (popcount.go:89)   ANDL    $63, AX
    0x0082 00130 (popcount.go:89)   ANDL    $63, CX
    0x0085 00133 (popcount.go:89)   ADDQ    CX, AX
    0x0088 00136 (popcount.go:89)   MOVQ    AX, "".~r1+16(FP)
    0x008d 00141 (popcount.go:89)   RET
    0x0000 48 8b 44 24 08 48 89 c1 48 c1 e8 20 48 89 c2 d1  H.D$.H..H.. H...
    0x0010 e8 25 55 55 55 55 29 c2 89 d0 81 e2 33 33 33 33  .%UUUU).....3333
    0x0020 c1 e8 02 25 33 33 33 33 01 d0 89 c2 c1 e8 04 01  ...%3333........
    0x0030 d0 25 0f 0f 0f 0f 89 c2 c1 e8 08 01 d0 89 c2 c1  .%..............
    0x0040 e8 10 01 d0 48 89 ca d1 e9 81 e1 55 55 55 55 29  ....H......UUUU)
    0x0050 ca 89 d1 81 e2 33 33 33 33 c1 e9 02 81 e1 33 33  .....3333.....33
    0x0060 33 33 01 d1 89 ca c1 e9 04 01 d1 81 e1 0f 0f 0f  33..............
    0x0070 0f 89 ca c1 e9 08 01 d1 89 ca c1 e9 10 01 d1 83  ................
    0x0080 e0 3f 83 e1 3f 48 01 c8 48 89 44 24 10 c3        .?..?H..H.D$..

Benchmark

$ go test -bench=.
BenchmarkCountBitsInt8PopCnt-4          500000000            3.96 ns/op
BenchmarkCountBitsInt16PopCnt-4         500000000            3.24 ns/op
BenchmarkCountBitsInt32PopCnt-4         500000000            3.36 ns/op
BenchmarkCountBitsInt64PopCnt-4         500000000            3.44 ns/op
BenchmarkCountBitsIntPopCnt-4           300000000            5.42 ns/op
BenchmarkCountBitsUint8PopCnt-4         1000000000           2.60 ns/op
BenchmarkCountBitsUint16PopCnt-4        1000000000           2.59 ns/op
BenchmarkCountBitsUint32PopCnt-4        1000000000           2.55 ns/op
> BenchmarkCountBitsUint64PopCnt-4        1000000000           2.51 ns/op
BenchmarkCountBitsUintPopCnt-4          300000000            4.38 ns/op
BenchmarkCountBitsBytePopCnt-4          500000000            3.21 ns/op
BenchmarkCountBitsRunePopCnt-4          500000000            3.29 ns/op
BenchmarkCountBitsInt8-4                2000000000           0.38 ns/op
BenchmarkCountBitsInt16-4               2000000000           0.41 ns/op
BenchmarkCountBitsInt32-4               2000000000           0.36 ns/op
BenchmarkCountBitsInt64-4               2000000000           0.37 ns/op
BenchmarkCountBitsInt-4                 200000000            6.36 ns/op
BenchmarkCountBitsUint16-4              2000000000           0.36 ns/op
BenchmarkCountBitsUint32-4              2000000000           0.35 ns/op
> BenchmarkCountBitsUint64-4              2000000000           0.37 ns/op
> BenchmarkCountBitsUint64Alt-4           200000000            7.06 ns/op
BenchmarkCountBitsUint-4                300000000            4.16 ns/op
BenchmarkCountBitsUintReference-4       100000000           16.9 ns/op
BenchmarkCountBitsByte-4                2000000000           0.36 ns/op
BenchmarkCountBitsByteAlt-4             2000000000           0.36 ns/op
BenchmarkCountBitsRune-4                2000000000           0.37 ns/op
PASS
ok      github.com/steakknife/hamming   42.730s
$

From https://github.com/steakknife/hamming

The testing call is calling straight into the assembly version:

   0x0177 00375 (popcnt_amd64_test.go:189) CALL    "".CountBitsUint64PopCnt(SB)
  • 写回答

1条回答 默认 最新

  • dqnhfbc3738 2016-10-12 04:38
    关注

    Solution

     // popcount_test.go:226
     func BenchmarkCountBitsUint64(b *testing.B) {
    +       stopDeadCodeElimination := 0
            for i := 0; i < b.N; i++ {
    -               CountBitsUint64(uint64(i))
    +               stopDeadCodeElimination |= CountBitsUint64(uint64(i))
            }
    +       b.Logf("stopDeadCodeElimination: %d", stopDeadCodeElimination)
     }
    
     func BenchmarkCountBitsUint64Alt(b *testing.B) {
    

    Explanation

    There is no problem with the Go/asm code itself.

    It's overly-aggressive dead-code elimination in Go-land in the benchmark.

    This only benchmarks an empty loop because the result expression is unused:

    Broken

    Go (before)

    // popcount_test.go:226
    func BenchmarkCountBitsUint64(b *testing.B) {
            for i := 0; i < b.N; i++ {
                    CountBitsUint64(uint64(i))
            }
    }
    

    Asm (before)

    "".BenchmarkCountBitsInt64(SB), $
    0-8
            0x0000 00000 (popcount_test.go:202)     NOP
            0x0000 00000 (popcount_test.go:202)     NOP
            0x0000 00000 (popcount_test.go:202)     FUNCDATA        $0, gclocals·87d20ce1b583
    90b294df80b886db78bf(SB)
            0x0000 00000 (popcount_test.go:202)     FUNCDATA        $1, gclocals·33cdeccccebe
    80329f1fdbee7f5874cb(SB)
            0x0000 00000 (popcount_test.go:203)     MOVQ    "".b+8(FP), AX
            0x0005 00005 (popcount_test.go:203)     MOVQ    $0, CX
            0x0007 00007 (popcount_test.go:203)     MOVQ    184(AX), DX
            0x000e 00014 (popcount_test.go:203)     CMPQ    CX, DX
            0x0011 00017 (popcount_test.go:203)     JGE     $0, 34
            0x0013 00019 (popcount_test.go:203)     INCQ    CX
            0x0016 00022 (popcount_test.go:203)     MOVQ    184(AX), DX
            0x001d 00029 (popcount_test.go:203)     CMPQ    CX, DX
            0x0020 00032 (popcount_test.go:203)     JLT     $0, 19
            0x0022 00034 (popcount_test.go:206)     RET
            0x0000 48 8b 44 24 08 31 c9 48 8b 90 b8 00 00 00 48 39  H.D$.1.H......H9
            0x0010 d1 7d 0f 48 ff c1 48 8b 90 b8 00 00 00 48 39 d1  .}.H..H......H9.
            0x0020 7c f1 c3
    

    Fixed

    Go (with stopDeadCodeElimination)

    // popcount_test.go:226
    func BenchmarkCountBitsUint64(b *testing.B) {
        stopDeadCodeElimination := 0
        for i := 0; i < b.N; i++ {
                stopDeadCodeElimination |= CountBitsUint64(uint64(i))
        }
        b.Logf("stopDeadCodeElimination: %d", stopDeadCodeElimination)
    }
    

    Asm (with stopDeadCodeElimination)

    "".BenchmarkCountBitsUint64 t=1 size=327 args=0x8 locals=0x50
        0x0000 00000 (popcount_test.go:226) TEXT    "".BenchmarkCountBitsUint64(SB), $80-8
        0x0000 00000 (popcount_test.go:226) MOVQ    (TLS), CX
        0x0009 00009 (popcount_test.go:226) CMPQ    SP, 16(CX)
        0x000d 00013 (popcount_test.go:226) JLS 317
        0x0013 00019 (popcount_test.go:226) SUBQ    $80, SP
        0x0017 00023 (popcount_test.go:226) MOVQ    BP, 72(SP)
        0x001c 00028 (popcount_test.go:226) LEAQ    72(SP), BP
        0x0021 00033 (popcount_test.go:226) FUNCDATA    $0, gclocals·51fa0e13d53d6bad7f86670d3edaeac6(SB)
        0x0021 00033 (popcount_test.go:226) FUNCDATA    $1, gclocals·21a8f585a14d020f181242c5256583dc(SB)
        0x0021 00033 (popcount_test.go:228) MOVQ    "".b+88(FP), AX
        0x0026 00038 (popcount_test.go:227) MOVQ    $0, CX
        0x0028 00040 (popcount_test.go:227) MOVQ    CX, DX
        0x002b 00043 (popcount_test.go:228) MOVQ    184(AX), BX
        0x0032 00050 (popcount_test.go:228) CMPQ    CX, BX
        0x0035 00053 (popcount_test.go:228) JGE $0, 166
        0x0037 00055 (popcount_test.go:228) LEAQ    1(CX), BX
        0x003b 00059 (popcount_test.go:229) MOVQ    CX, SI
        0x003e 00062 (popcount_test.go:229) SHRQ    $1, CX
        0x0041 00065 (popcount_test.go:229) MOVQ    $6148914691236517205, DI
        0x004b 00075 (popcount_test.go:229) ANDQ    CX, DI
        0x004e 00078 (popcount_test.go:229) SUBQ    DI, SI
        0x0051 00081 (popcount_test.go:229) MOVQ    $3689348814741910323, DI
        0x005b 00091 (popcount_test.go:229) MOVQ    SI, R8
        0x005e 00094 (popcount_test.go:229) ANDQ    DI, SI
        0x0061 00097 (popcount_test.go:229) SHRQ    $2, R8
        0x0065 00101 (popcount_test.go:229) ANDQ    R8, DI
        0x0068 00104 (popcount_test.go:229) ADDQ    DI, SI
        0x006b 00107 (popcount_test.go:229) MOVQ    SI, DI
        0x006e 00110 (popcount_test.go:229) SHRQ    $4, SI
        0x0072 00114 (popcount_test.go:229) ADDQ    DI, SI
        0x0075 00117 (popcount_test.go:229) MOVQ    $1085102592571150095, DI
        0x007f 00127 (popcount_test.go:229) ANDQ    DI, SI
        0x0082 00130 (popcount_test.go:229) MOVQ    $72340172838076673, DI
        0x008c 00140 (popcount_test.go:229) IMULQ   DI, SI
        0x0090 00144 (popcount_test.go:229) SHRQ    $56, SI
        0x0094 00148 (popcount_test.go:229) ORQ SI, DX
        0x0097 00151 (popcount_test.go:228) MOVQ    BX, CX
        0x009a 00154 (popcount_test.go:228) MOVQ    184(AX), BX
        0x00a1 00161 (popcount_test.go:228) CMPQ    CX, BX
        0x00a4 00164 (popcount_test.go:228) JLT $0, 55
        0x00a6 00166 (popcount_test.go:231) MOVQ    DX, "".autotmp_1657+48(SP)
        0x00ab 00171 (popcount_test.go:231) MOVQ    $0, "".autotmp_1663+56(SP)
        0x00b4 00180 (popcount_test.go:231) MOVQ    $0, "".autotmp_1663+64(SP)
        0x00bd 00189 (popcount_test.go:231) LEAQ    type.int(SB), CX
        0x00c4 00196 (popcount_test.go:231) MOVQ    CX, (SP)
        0x00c8 00200 (popcount_test.go:231) LEAQ    "".autotmp_1657+48(SP), CX
        0x00cd 00205 (popcount_test.go:231) MOVQ    CX, 8(SP)
        0x00d2 00210 (popcount_test.go:231) MOVQ    $0, 16(SP)
        0x00db 00219 (popcount_test.go:231) PCDATA  $0, $1
        0x00db 00219 (popcount_test.go:231) CALL    runtime.convT2E(SB)
        0x00e0 00224 (popcount_test.go:231) MOVQ    24(SP), AX
        0x00e5 00229 (popcount_test.go:231) MOVQ    32(SP), CX
        0x00ea 00234 (popcount_test.go:231) MOVQ    AX, "".autotmp_1663+56(SP)
        0x00ef 00239 (popcount_test.go:231) MOVQ    CX, "".autotmp_1663+64(SP)
        0x00f4 00244 (popcount_test.go:231) MOVQ    "".b+88(FP), AX
        0x00f9 00249 (popcount_test.go:231) MOVQ    AX, (SP)
        0x00fd 00253 (popcount_test.go:231) LEAQ    go.string."stopDeadCodeElimination: %d"(SB), CX
        0x0104 00260 (popcount_test.go:231) MOVQ    CX, 8(SP)
        0x0109 00265 (popcount_test.go:231) MOVQ    $27, 16(SP)
        0x0112 00274 (popcount_test.go:231) LEAQ    "".autotmp_1663+56(SP), CX
        0x0117 00279 (popcount_test.go:231) MOVQ    CX, 24(SP)
        0x011c 00284 (popcount_test.go:231) MOVQ    $1, 32(SP)
        0x0125 00293 (popcount_test.go:231) MOVQ    $1, 40(SP)
        0x012e 00302 (popcount_test.go:231) PCDATA  $0, $1
        0x012e 00302 (popcount_test.go:231) CALL    testing.(*common).Logf(SB)
        0x0133 00307 (popcount_test.go:232) MOVQ    72(SP), BP
        0x0138 00312 (popcount_test.go:232) ADDQ    $80, SP
        0x013c 00316 (popcount_test.go:232) RET
        0x013d 00317 (popcount_test.go:232) NOP
        0x013d 00317 (popcount_test.go:226) CALL    runtime.morestack_noctxt(SB)
        0x0142 00322 (popcount_test.go:226) JMP 0
        0x0000 65 48 8b 0c 25 00 00 00 00 48 3b 61 10 0f 86 2a  eH..%....H;a...*
        0x0010 01 00 00 48 83 ec 50 48 89 6c 24 48 48 8d 6c 24  ...H..PH.l$HH.l$
        0x0020 48 48 8b 44 24 58 31 c9 48 89 ca 48 8b 98 b8 00  HH.D$X1.H..H....
        0x0030 00 00 48 39 d9 7d 6f 48 8d 59 01 48 89 ce 48 d1  ..H9.}oH.Y.H..H.
        0x0040 e9 48 bf 55 55 55 55 55 55 55 55 48 21 cf 48 29  .H.UUUUUUUUH!.H)
        0x0050 fe 48 bf 33 33 33 33 33 33 33 33 49 89 f0 48 21  .H.33333333I..H!
        0x0060 fe 49 c1 e8 02 4c 21 c7 48 01 fe 48 89 f7 48 c1  .I...L!.H..H..H.
        0x0070 ee 04 48 01 fe 48 bf 0f 0f 0f 0f 0f 0f 0f 0f 48  ..H..H.........H
        0x0080 21 fe 48 bf 01 01 01 01 01 01 01 01 48 0f af f7  !.H.........H...
        0x0090 48 c1 ee 38 48 09 f2 48 89 d9 48 8b 98 b8 00 00  H..8H..H..H.....
        0x00a0 00 48 39 d9 7c 91 48 89 54 24 30 48 c7 44 24 38  .H9.|.H.T$0H.D$8
        0x00b0 00 00 00 00 48 c7 44 24 40 00 00 00 00 48 8d 0d  ....H.D$@....H..
        0x00c0 00 00 00 00 48 89 0c 24 48 8d 4c 24 30 48 89 4c  ....H..$H.L$0H.L
        0x00d0 24 08 48 c7 44 24 10 00 00 00 00 e8 00 00 00 00  $.H.D$..........
        0x00e0 48 8b 44 24 18 48 8b 4c 24 20 48 89 44 24 38 48  H.D$.H.L$ H.D$8H
        0x00f0 89 4c 24 40 48 8b 44 24 58 48 89 04 24 48 8d 0d  .L$@H.D$XH..$H..
        0x0100 00 00 00 00 48 89 4c 24 08 48 c7 44 24 10 1b 00  ....H.L$.H.D$...
        0x0110 00 00 48 8d 4c 24 38 48 89 4c 24 18 48 c7 44 24  ..H.L$8H.L$.H.D$
        0x0120 20 01 00 00 00 48 c7 44 24 28 01 00 00 00 e8 00   ....H.D$(......
        0x0130 00 00 00 48 8b 6c 24 48 48 83 c4 50 c3 e8 00 00  ...H.l$HH..P....
        0x0140 00 00 e9 b9 fe ff ff                             .......
        rel 5+4 t=15 TLS+0
        rel 192+4 t=14 type.int+0
        rel 220+4 t=7 runtime.convT2E+0
        rel 256+4 t=14 go.string."stopDeadCodeElimination: %d"+0
        rel 303+4 t=7 testing.(*common).Logf+0
        rel 318+4 t=7 runtime.morestack_noctxt+0
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 划分vlan后不通了
  • ¥15 GDI处理通道视频时总是带有白色锯齿
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大