国产日韩精品视频_2020久久国产最新免费观看_国内久久久久影院精品_日本一区二区视频在线

為什么小的變化會(huì)對我的numba并行函數(shù)的運(yùn)行時(shí)產(chǎn)生巨大的影響?

我正在嘗試?yán)斫鉃槭裁次业牟⑿衝umba函數(shù)的行為方式是這樣的。特別是,為什么它對arrays的使用方式如此敏感。

我有以下功能:

@njit(parallel=True)
def f(n):
    g = lambda i,j: zeros(3) + sqrt(i*j)
    x = zeros((n,3))
    for i in prange(n):
        for j in range(n):
            tmp      = g(i,j)
            x[i] += tmp
    return x

相信n足夠大,并行計(jì)算才有用。由于某些原因,這實(shí)際上使用更少的內(nèi)核運(yùn)行得更快?,F(xiàn)在,當(dāng)我做一個(gè)小改變時(shí)(x[i]->x[i, :])。

@njit(parallel=True)
def f(n):
    g = lambda i,j: zeros(3) + sqrt(i*j)
    x = zeros((n,3))
    for i in prange(n):
        for j in range(n):
            tmp      = g(i,j)
            x[i, :] += tmp
    return x

性能明顯更好,并且可以隨內(nèi)核數(shù)量適當(dāng)擴(kuò)展(即,內(nèi)核越多越快)。為什么切片會(huì)使性能更好?更進(jìn)一步說,另一個(gè)有很大不同的變化是將lambda函數(shù)轉(zhuǎn)換為外部njt函數(shù)。

@njit
def g(i,j):
    x = zeros(3) + sqrt(i*j)
    return x

@njit(parallel=True)
def f(n):
    x = zeros((n,3))
    for i in prange(n):
        for j in range(n):
            tmp      = g(i,j)
            x[i, :] += tmp
    return x

這再次破壞了性能和擴(kuò)展,恢復(fù)到與第一種情況相同或更低的運(yùn)行時(shí)。為什么這個(gè)外部函數(shù)會(huì)破壞性能?可以使用以下兩個(gè)選項(xiàng)恢復(fù)性能。

@njit
def g(i,j):
    x = sqrt(i*j)
    return x

@njit(parallel=True)
def f(n):
    x = zeros((n,3))
    for i in prange(n):
        for j in range(n):
            tmp      = zeros(3) + g(i,j)
            x[i, :] += tmp
    return x
@njit(parallel=True)
def f(n):
    def g(i,j):
        x = zeros(3) + sqrt(i*j)
        return x
    x = zeros((n,3))
    for i in prange(n):
        for j in range(n):
            tmp      = g(i,j)
            x[i, :] += tmp
    return x

為什么parallel=True numba修飾函數(shù)對arrays的使用方式如此敏感?我知道arrays不是簡單的可并行化的,但這些變化顯著影響性能的確切原因?qū)ξ襾碚f并不明顯。

? 最佳回答:

TL;DR:分配和內(nèi)聯(lián)當(dāng)然是不同版本之間性能差距的根源。

在Numpy陣列上操作通常比在Numba中查看要貴一點(diǎn)。在這種情況下,問題似乎是Numba在使用x[i]時(shí)執(zhí)行分配,而不使用{%12}。問題是分配是昂貴的,特別是在并行代碼中,因?yàn)榉峙淦魍豢缮炜s(由于內(nèi)部鎖或序列化執(zhí)行的原子變量)。我不確定這是否錯(cuò)過了優(yōu)化,因?yàn)?code>x[i]和x[i,:]的行為可能略有不同。

此外,Numba使用JIT編譯器(LLVM-Lite)來執(zhí)行積極的優(yōu)化。LLVM能夠跟蹤分配,以便在簡單的情況下刪除它們(如函數(shù)在同一范圍內(nèi)執(zhí)行分配并釋放數(shù)據(jù),而不會(huì)產(chǎn)生副作用)。問題是Numba分配正在調(diào)用編譯器無法優(yōu)化的外部函數(shù),因?yàn)樗诰幾g時(shí)不知道內(nèi)容(由于Numba運(yùn)行時(shí)接口當(dāng)前的工作方式),并且該函數(shù)理論上可能會(huì)產(chǎn)生副作用。

為了顯示發(fā)生了什么,我們需要深入研究匯編代碼??傊?,Numba為f在N threads中調(diào)用xxx_numba_parfor_gufunc_xxx函數(shù)生成了一個(gè)函數(shù)。最后一個(gè)函數(shù)執(zhí)行并行循環(huán)的內(nèi)容。兩種實(shí)現(xiàn)的調(diào)用者函數(shù)都相同。兩個(gè)版本的主要計(jì)算功能不同。這是我機(jī)器上的裝配代碼:

    -----  WITHOUT VIEWS  ----- 

_ZN13_3cdynamic_3e40__numba_parfor_gufunc_0x272d183ed00_2487B104c8tJTC_2fWQAkyW1xhBopo9CCDiCFCDMJHDTCIGCy8IDxIcEFloKEF4UEDC8KBhhWIo6mjgJZwoWpwJVOYNCIkbcG2Ai0vgkhqAgA_3dE5ArrayIyLi1E1C7mutable7alignedE23Literal_5bint_5d_283_29x5ArrayIdLi2E1C7mutable7alignedE:
        .cfi_startproc
        pushq   %r15
        .cfi_def_cfa_offset 16
        pushq   %r14
        .cfi_def_cfa_offset 24
        pushq   %r13
        .cfi_def_cfa_offset 32
        pushq   %r12
        .cfi_def_cfa_offset 40
        pushq   %rsi
        .cfi_def_cfa_offset 48
        pushq   %rdi
        .cfi_def_cfa_offset 56
        pushq   %rbp
        .cfi_def_cfa_offset 64
        pushq   %rbx
        .cfi_def_cfa_offset 72
        subq    $280, %rsp
        vmovaps %xmm6, 256(%rsp)
        .cfi_def_cfa_offset 352
        .cfi_offset %rbx, -72
        .cfi_offset %rbp, -64
        .cfi_offset %rdi, -56
        .cfi_offset %rsi, -48
        .cfi_offset %r12, -40
        .cfi_offset %r13, -32
        .cfi_offset %r14, -24
        .cfi_offset %r15, -16
        .cfi_offset %xmm6, -96
        movq    %rdx, 160(%rsp)
        movq    %rcx, 200(%rsp)
        movq    504(%rsp), %r14
        movq    488(%rsp), %r15
        leaq    -1(%r15), %rax
        imulq   %r14, %rax
        xorl    %ebp, %ebp
        testq   %rax, %rax
        movq    %rax, %rdx
        cmovnsq %rbp, %rdx
        cmpq    $1, %r15
        cmovbq  %rbp, %rdx
        movq    %rdx, 240(%rsp)
        movq    %rax, %rdx
        sarq    $63, %rdx
        andnq   %rax, %rdx, %rax
        addq    464(%rsp), %rax
        movq    %r15, %rbx
        subq    $1, %rbx
        movq    440(%rsp), %rcx
        movq    400(%rsp), %rsi
        movabsq $NRT_incref, %rdx
        cmovbq  %rbp, %rax
        movq    %rax, 232(%rsp)
        callq   *%rdx
        movq    (%rsi), %rbp
        movq    8(%rsi), %rdi
        subq    %rbp, %rdi
        incq    %rdi
        movabsq $NRT_MemInfo_alloc_safe_aligned, %rsi
        movl    $24, %ecx
        movl    $32, %edx
        callq   *%rsi
        movq    %rax, 192(%rsp)
        movq    24(%rax), %rax
        movq    %rax, 120(%rsp)
        movl    $24, %ecx
        movl    $32, %edx
        callq   *%rsi
        movq    %rax, 64(%rsp)
        testq   %rdi, %rdi
        jle     .LBB6_48
        movq    %rdi, %r11
        movq    %rbp, %r8
        movq    %rbx, %r10
        movq    %r15, %r9
        movq    432(%rsp), %rdx
        movq    472(%rsp), %rdi
        movq    %r15, %rax
        imulq   464(%rsp), %rax
        movq    %rax, 208(%rsp)
        xorl    %eax, %eax
        testq   %rdx, %rdx
        setg    %al
        movq    %rdx, %rcx
        sarq    $63, %rcx
        andnq   %rdx, %rcx, %rcx
        subq    %rax, %rcx
        movq    %rcx, 224(%rsp)
        leaq    -4(%r15), %rax
        movq    %rax, 184(%rsp)
        shrq    $2, %rax
        incq    %rax
        andl    $7, %r15d
        movq    %r9, %r13
        andq    $-8, %r13
        movq    %r9, %rcx
        andq    $-4, %rcx
        movq    %rcx, 176(%rsp)
        movl    %eax, %ecx
        andl    $7, %ecx
        movq    %rbp, %rdx
        imulq   %r9, %rdx
        movq    %rcx, 168(%rsp)
        shlq    $5, %rcx
        movq    %rcx, 152(%rsp)
        andq    $-8, %rax
        addq    $-8, %rax
        movq    %rax, 144(%rsp)
        movq    %rax, %rcx
        shrq    $3, %rcx
        incq    %rcx
        movq    %rcx, %rax
        movq    %rcx, 136(%rsp)
        andq    $-2, %rcx
        movq    %rcx, 128(%rsp)
        vxorps  %xmm6, %xmm6, %xmm6
        movq    64(%rsp), %rax
        movq    24(%rax), %rax
        movq    %rax, 248(%rsp)
        leaq    56(%rdi,%rdx,8), %rsi
        leaq    224(%rdi,%rdx,8), %rcx
        leaq    (,%r9,8), %rax
        movq    %rax, 88(%rsp)
        leaq    (%rdi,%rdx,8), %rax
        addq    $480, %rax
        movq    %rax, 80(%rsp)
        xorl    %eax, %eax
        movq    %rax, 96(%rsp)
        movq    %rdx, 216(%rsp)
        movq    %rdx, 112(%rsp)
        movq    %rbx, 56(%rsp)
        jmp     .LBB6_3
        .p2align        4, 0x90
.LBB6_2:
        leaq    -1(%r11), %rax
        incq    %r8
        addq    %r9, 112(%rsp)
        movq    104(%rsp), %rcx
        leaq    (%rcx,%r9,8), %rcx
        incq    96(%rsp)
        movq    88(%rsp), %rdx
        addq    %rdx, %rsi
        addq    %rdx, 80(%rsp)
        cmpq    $2, %r11
        movq    %rax, %r11
        jl      .LBB6_48
.LBB6_3:
        movq    %rcx, 104(%rsp)
        movq    %r8, %rax
        imulq   %r9, %rax
        movq    472(%rsp), %rdi
        leaq    (%rdi,%rax,8), %rbp
        movq    240(%rsp), %rax
        addq    %rbp, %rax
        movq    232(%rsp), %rcx
        addq    %rbp, %rcx
        movq    %r8, %rdx
        imulq   496(%rsp), %rdx
        movq    464(%rsp), %rbx
        addq    %rdx, %rbx
        testq   %r9, %r9
        cmoveq  %r9, %rdx
        cmoveq  %r9, %rbx
        addq    %rdi, %rdx
        addq    %rdi, %rbx
        cmpq    %rbx, %rax
        setb    39(%rsp)
        cmpq    %rcx, %rdx
        setb    %al
        cmpq    $0, 432(%rsp)
        jle     .LBB6_2
        cmpq    424(%rsp), %r9
        jne     .LBB6_46
        movq    96(%rsp), %rcx
        imulq   %r9, %rcx
        addq    216(%rsp), %rcx
        andb    %al, 39(%rsp)
        movq    472(%rsp), %rax
        leaq    (%rax,%rcx,8), %rax
        movq    %rax, 72(%rsp)
        movl    $1, %eax
        movq    224(%rsp), %rbx
        xorl    %r12d, %r12d
        .p2align        4, 0x90
.LBB6_6:
        imulq   %r8, %r12
        vcvtsi2sd       %r12, %xmm2, %xmm0
        vsqrtsd %xmm0, %xmm0, %xmm0
        movq    120(%rsp), %rcx
        vmovups %xmm6, (%rcx)
        movq    $0, 16(%rcx)
        movq    248(%rsp), %rdx
        vmovsd  %xmm0, (%rdx)
        vaddsd  (%rbp), %xmm0, %xmm1
        vmovsd  %xmm1, (%rbp)
        vaddsd  8(%rcx), %xmm0, %xmm1
        vmovsd  %xmm1, 8(%rdx)
        vaddsd  8(%rbp), %xmm1, %xmm1
        vmovsd  %xmm1, 8(%rbp)
        vaddsd  16(%rcx), %xmm0, %xmm0
        vmovsd  %xmm0, 16(%rdx)
        movq    %rax, %r12
        vaddsd  16(%rbp), %xmm0, %xmm0
        vmovsd  %xmm0, 16(%rbp)
        cmpb    $0, 39(%rsp)
        jne     .LBB6_7
        testq   %r9, %r9
        jle     .LBB6_28
        cmpq    $7, %r10
        jae     .LBB6_19
        xorl    %eax, %eax
        movq    %rbp, %rdi
        testq   %r15, %r15
        jne     .LBB6_23
        jmp     .LBB6_26
        .p2align        4, 0x90
.LBB6_19:
        movq    %rbp, %rcx
        xorl    %eax, %eax
        .p2align        4, 0x90
.LBB6_20:
        movq    (%rcx), %rdx
        movq    %rdx, -56(%rsi,%rax,8)
        leaq    (%r14,%rcx), %rdx
        movq    (%r14,%rcx), %rcx
        movq    %rcx, -48(%rsi,%rax,8)
        leaq    (%r14,%rdx), %rcx
        movq    (%r14,%rdx), %rdx
        movq    %rdx, -40(%rsi,%rax,8)
        leaq    (%r14,%rcx), %rdx
        movq    (%r14,%rcx), %rcx
        movq    %rcx, -32(%rsi,%rax,8)
        leaq    (%r14,%rdx), %rcx
        movq    (%r14,%rdx), %rdx
        movq    %rdx, -24(%rsi,%rax,8)
        leaq    (%r14,%rcx), %rdx
        movq    (%r14,%rcx), %rcx
        movq    %rcx, -16(%rsi,%rax,8)
        leaq    (%r14,%rdx), %rdi
        movq    (%r14,%rdx), %rcx
        movq    %rcx, -8(%rsi,%rax,8)
        leaq    (%r14,%rdi), %rcx
        movq    (%r14,%rdi), %rdx
        movq    %rdx, (%rsi,%rax,8)
        addq    $8, %rax
        addq    %r14, %rcx
        cmpq    %rax, %r13
        jne     .LBB6_20
        movq    %r13, %rax
        movq    %rbp, %rdi
        testq   %r15, %r15
        je      .LBB6_26
.LBB6_23:
        movq    112(%rsp), %rcx
        addq    %rax, %rcx
        imulq   %r14, %rax
        addq    %rbp, %rax
        movq    472(%rsp), %rdx
        leaq    (%rdx,%rcx,8), %rcx
        xorl    %edx, %edx
        .p2align        4, 0x90
.LBB6_24:
        movq    (%rax), %rdi
        movq    %rdi, (%rcx,%rdx,8)
        incq    %rdx
        addq    %r14, %rax
        cmpq    %rdx, %r15
        jne     .LBB6_24
        movq    %rbp, %rdi
.LBB6_26:
        cmpb    $0, 39(%rsp)
        jne     .LBB6_27
.LBB6_28:
        xorl    %eax, %eax
        testq   %rbx, %rbx
        setg    %al
        movq    %rbx, %rcx
        subq    %rax, %rcx
        addq    %r12, %rax
        testq   %rbx, %rbx
        movq    %rcx, %rbx
        jg      .LBB6_6
        jmp     .LBB6_2
.LBB6_7:
        movq    %r11, 48(%rsp)
        movq    %r8, 40(%rsp)
        movq    208(%rsp), %rcx
        movabsq $NRT_Allocate, %rax
        vzeroupper
        callq   *%rax
        movq    488(%rsp), %r9
        movq    %rax, %rdi
        testq   %r9, %r9
        jle     .LBB6_8
        movq    56(%rsp), %r10
        cmpq    $7, %r10
        movq    48(%rsp), %r11
        jae     .LBB6_11
        xorl    %eax, %eax
        testq   %r15, %r15
        jne     .LBB6_15
        jmp     .LBB6_17
.LBB6_8:
        movq    40(%rsp), %r8
        movq    48(%rsp), %r11
.LBB6_27:
        movq    %r8, 40(%rsp)
        movq    %rdi, %rcx
        movq    %r11, %rdi
        movabsq $NRT_Free, %rax
        vzeroupper
        callq   *%rax
        movq    %rdi, %r11
        movq    40(%rsp), %r8
        movq    56(%rsp), %r10
        movq    488(%rsp), %r9
        jmp     .LBB6_28
.LBB6_11:
        movq    %rbp, %rcx
        xorl    %eax, %eax
        .p2align        4, 0x90
.LBB6_12:
        movq    (%rcx), %rdx
        movq    %rdx, (%rdi,%rax,8)
        leaq    (%r14,%rcx), %rdx
        movq    (%r14,%rcx), %rcx
        movq    %rcx, 8(%rdi,%rax,8)
        leaq    (%r14,%rdx), %rcx
        movq    (%r14,%rdx), %rdx
        movq    %rdx, 16(%rdi,%rax,8)
        leaq    (%r14,%rcx), %rdx
        movq    (%r14,%rcx), %rcx
        movq    %rcx, 24(%rdi,%rax,8)
        leaq    (%r14,%rdx), %rcx
        movq    (%r14,%rdx), %rdx
        movq    %rdx, 32(%rdi,%rax,8)
        leaq    (%r14,%rcx), %rdx
        movq    (%r14,%rcx), %rcx
        movq    %rcx, 40(%rdi,%rax,8)
        leaq    (%r14,%rdx), %r8
        movq    (%r14,%rdx), %rcx
        movq    %rcx, 48(%rdi,%rax,8)
        leaq    (%r14,%r8), %rcx
        movq    (%r14,%r8), %rdx
        movq    %rdx, 56(%rdi,%rax,8)
        addq    $8, %rax
        addq    %r14, %rcx
        cmpq    %rax, %r13
        jne     .LBB6_12
        movq    %r13, %rax
        testq   %r15, %r15
        je      .LBB6_17
.LBB6_15:
        leaq    (%rdi,%rax,8), %r8
        imulq   %r14, %rax
        addq    %rbp, %rax
        xorl    %edx, %edx
        .p2align        4, 0x90
.LBB6_16:
        movq    (%rax), %rcx
        movq    %rcx, (%r8,%rdx,8)
        incq    %rdx
        addq    %r14, %rax
        cmpq    %rdx, %r15
        jne     .LBB6_16
.LBB6_17:
        testq   %r9, %r9
        jle     .LBB6_18
        cmpq    $3, %r9
        movq    40(%rsp), %r8
        ja      .LBB6_32
        xorl    %eax, %eax
        jmp     .LBB6_31
.LBB6_32:
        cmpq    $28, 184(%rsp)
        jae     .LBB6_34
        xorl    %eax, %eax
        jmp     .LBB6_40
.LBB6_34:
        cmpq    $0, 144(%rsp)
        je      .LBB6_35
        movq    128(%rsp), %rcx
        xorl    %eax, %eax
        movq    80(%rsp), %rdx
        .p2align        4, 0x90
.LBB6_37:
        vmovups (%rdi,%rax,8), %ymm0
        vmovups %ymm0, -480(%rdx,%rax,8)
        vmovups 32(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -448(%rdx,%rax,8)
        vmovups 64(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -416(%rdx,%rax,8)
        vmovups 96(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -384(%rdx,%rax,8)
        vmovups 128(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -352(%rdx,%rax,8)
        vmovups 160(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -320(%rdx,%rax,8)
        vmovups 192(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -288(%rdx,%rax,8)
        vmovups 224(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -256(%rdx,%rax,8)
        vmovups 256(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -224(%rdx,%rax,8)
        vmovups 288(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -192(%rdx,%rax,8)
        vmovups 320(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -160(%rdx,%rax,8)
        vmovups 352(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -128(%rdx,%rax,8)
        vmovups 384(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -96(%rdx,%rax,8)
        vmovups 416(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -64(%rdx,%rax,8)
        vmovups 448(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -32(%rdx,%rax,8)
        vmovupd 480(%rdi,%rax,8), %ymm0
        vmovupd %ymm0, (%rdx,%rax,8)
        addq    $64, %rax
        addq    $-2, %rcx
        jne     .LBB6_37
        testb   $1, 136(%rsp)
        je      .LBB6_40
.LBB6_39:
        vmovups (%rdi,%rax,8), %ymm0
        movq    104(%rsp), %rcx
        vmovups %ymm0, -224(%rcx,%rax,8)
        vmovups 32(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -192(%rcx,%rax,8)
        vmovups 64(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -160(%rcx,%rax,8)
        vmovups 96(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -128(%rcx,%rax,8)
        vmovups 128(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -96(%rcx,%rax,8)
        vmovups 160(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -64(%rcx,%rax,8)
        vmovups 192(%rdi,%rax,8), %ymm0
        vmovups %ymm0, -32(%rcx,%rax,8)
        vmovupd 224(%rdi,%rax,8), %ymm0
        vmovupd %ymm0, (%rcx,%rax,8)
        addq    $32, %rax
.LBB6_40:
        cmpq    $0, 168(%rsp)
        je      .LBB6_42
        movq    72(%rsp), %rcx
        leaq    (%rcx,%rax,8), %rcx
        leaq    (%rdi,%rax,8), %rdx
        movq    152(%rsp), %r8
        movabsq $memcpy, %rax
        vzeroupper
        callq   *%rax
        movq    48(%rsp), %r11
        movq    40(%rsp), %r8
        movq    488(%rsp), %r9
.LBB6_42:
        movq    176(%rsp), %rcx
        movq    %rcx, %rax
        cmpq    %r9, %rcx
        movq    56(%rsp), %r10
        je      .LBB6_26
.LBB6_31:
        movq    72(%rsp), %rcx
        leaq    (%rcx,%rax,8), %rcx
        leaq    (%rdi,%rax,8), %rdx
        shlq    $3, %rax
        movq    88(%rsp), %r8
        subq    %rax, %r8
        movabsq $memcpy, %rax
        vzeroupper
        callq   *%rax
        movq    48(%rsp), %r11
        movq    40(%rsp), %r8
        movq    56(%rsp), %r10
        movq    488(%rsp), %r9
        jmp     .LBB6_26
.LBB6_35:
        xorl    %eax, %eax
        testb   $1, 136(%rsp)
        jne     .LBB6_39
        jmp     .LBB6_40
.LBB6_18:
        movq    40(%rsp), %r8
        jmp     .LBB6_26
.LBB6_48:
        movabsq $NRT_decref, %rsi
        movq    440(%rsp), %rcx
        vzeroupper
        callq   *%rsi
        movq    192(%rsp), %rcx
        callq   *%rsi
        movq    64(%rsp), %rcx
        callq   *%rsi
        movq    200(%rsp), %rax
        movq    $0, (%rax)
        xorl    %eax, %eax
        jmp     .LBB6_47
.LBB6_46:
        vxorps  %xmm0, %xmm0, %xmm0
        movq    120(%rsp), %rax
        vmovups %xmm0, (%rax)
        movq    $0, 16(%rax)
        movq    440(%rsp), %rcx
        movabsq $NRT_incref, %rax
        vzeroupper
        callq   *%rax
        movabsq $.const.picklebuf.2691622873664, %rax
        movq    160(%rsp), %rcx
        movq    %rax, (%rcx)
        movl    $1, %eax
.LBB6_47:
        vmovaps 256(%rsp), %xmm6
        addq    $280, %rsp
        popq    %rbx
        popq    %rbp
        popq    %rdi
        popq    %rsi
        popq    %r12
        popq    %r13
        popq    %r14
        popq    %r15
        retq
.Lfunc_end6:
        .size   _ZN13_3cdynamic_3e40__numba_parfor_gufunc_0x272d183ed00_2487B104c8tJTC_2fWQAkyW1xhBopo9CCDiCFCDMJHDTCIGCy8IDxIcEFloKEF4UEDC8KBhhWIo6mjgJZwoWpwJVOYNCIkbcG2Ai0vgkhqAgA_3dE5ArrayIyLi1E1C7mutable7alignedE23Literal_5bint_5d_283_29x5ArrayIdLi2E1C7mutable7alignedE, .Lfunc_end6-_ZN13_3cdynamic_3e40__numba_parfor_gufunc_0x272d183ed00_2487B104c8tJTC_2fWQAkyW1xhBopo9CCDiCFCDMJHDTCIGCy8IDxIcEFloKEF4UEDC8KBhhWIo6mjgJZwoWpwJVOYNCIkbcG2Ai0vgkhqAgA_3dE5ArrayIyLi1E1C7mutable7alignedE23Literal_5bint_5d_283_29x5ArrayIdLi2E1C7mutable7alignedE
        .cfi_endproc

        .weak   NRT_incref
        .p2align        4, 0x90
        .type   NRT_incref,@function
NRT_incref:
        testq   %rcx, %rcx
        je      .LBB7_1
        lock            incq    (%rcx)
        retq
.LBB7_1:
        retq
.Lfunc_end7:
    -----   WITH VIEWS    -----

__gufunc__._ZN13_3cdynamic_3e40__numba_parfor_gufunc_0x272bef6ed00_2491B104c8tJTC_2fWQAkyW1xhBopo9CCDiCFCDMJHDTCIGCy8IDxIcEFloKEF4UEDC8KBhhWIo6mjgJZwoWpwJVOYNCIkbcG2Ai0vgkhqAgA_3dE5ArrayIyLi1E1C7mutable7alignedE23Literal_5bint_5d_283_29x5ArrayIdLi2E1C7mutable7alignedE:
        .cfi_startproc
        pushq   %r15
        .cfi_def_cfa_offset 16
        pushq   %r14
        .cfi_def_cfa_offset 24
        pushq   %r13
        .cfi_def_cfa_offset 32
        pushq   %r12
        .cfi_def_cfa_offset 40
        pushq   %rsi
        .cfi_def_cfa_offset 48
        pushq   %rdi
        .cfi_def_cfa_offset 56
        pushq   %rbp
        .cfi_def_cfa_offset 64
        pushq   %rbx
        .cfi_def_cfa_offset 72
        subq    $168, %rsp
        vmovaps %xmm6, 144(%rsp)
        .cfi_def_cfa_offset 240
        .cfi_offset %rbx, -72
        .cfi_offset %rbp, -64
        .cfi_offset %rdi, -56
        .cfi_offset %rsi, -48
        .cfi_offset %r12, -40
        .cfi_offset %r13, -32
        .cfi_offset %r14, -24
        .cfi_offset %r15, -16
        .cfi_offset %xmm6, -96
        movq    (%rdx), %rax
        movq    24(%rdx), %r12
        movq    (%rcx), %rdx
        movq    %rdx, 120(%rsp)
        movq    8(%rcx), %rdx
        movq    %rdx, 112(%rsp)
        movq    (%r8), %rdx
        movq    %rdx, 104(%rsp)
        movq    8(%r8), %rdx
        movq    %rdx, 96(%rsp)
        movq    16(%rcx), %rdx
        movq    %rdx, 88(%rsp)
        movq    16(%r8), %rdx
        movq    %rdx, 80(%rsp)
        movq    24(%rcx), %rcx
        movq    %rcx, 64(%rsp)
        movq    24(%r8), %rcx
        movq    %rcx, 56(%rsp)
        movl    $0, 36(%rsp)
        movq    %rax, 72(%rsp)
        testq   %rax, %rax
        jle     .LBB5_12
        cmpq    $4, %r12
        movl    $3, %eax
        cmovlq  %r12, %rax
        movq    %rax, 48(%rsp)
        movq    %r12, %rbx
        sarq    $63, %rbx
        andq    %r12, %rbx
        xorl    %eax, %eax
        vxorps  %xmm6, %xmm6, %xmm6
        jmp     .LBB5_2
        .p2align        4, 0x90
.LBB5_9:
        movq    136(%rsp), %rcx
        movabsq $NRT_decref, %rsi
        movq    %r9, %rdi
        callq   *%rsi
        movq    %rdi, %rcx
        callq   *%rsi
        movq    40(%rsp), %rax
        incq    %rax
        cmpq    72(%rsp), %rax
        je      .LBB5_12
.LBB5_2:
        movq    %rax, %rbp
        imulq   104(%rsp), %rbp
        movq    %rax, %rcx
        imulq   96(%rsp), %rcx
        movq    112(%rsp), %rdx
        movq    (%rdx,%rcx), %rcx
        movq    %rcx, 128(%rsp)
        movq    %rax, 40(%rsp)
        movq    %rax, %rcx
        imulq   80(%rsp), %rcx
        movq    88(%rsp), %rdx
        movq    (%rdx,%rcx), %rdi
        movq    120(%rsp), %rcx
        movq    (%rbp,%rcx), %r13
        movq    8(%rbp,%rcx), %r14
        subq    %r13, %r14
        incq    %r14
        movl    $24, %ecx
        movl    $32, %edx
        movabsq $NRT_MemInfo_alloc_safe_aligned, %rsi
        callq   *%rsi
        movq    %rax, 136(%rsp)
        movq    24(%rax), %r15
        movl    $24, %ecx
        movl    $32, %edx
        callq   *%rsi
        movq    %rax, %r9
        testq   %r14, %r14
        jle     .LBB5_9
        xorl    %edx, %edx
        testq   %rdi, %rdi
        setg    %r8b
        testq   %rdi, %rdi
        jle     .LBB5_9
        movq    128(%rsp), %rax
        cmpq    %rax, 48(%rsp)
        jne     .LBB5_10
        movq    40(%rsp), %rax
        imulq   56(%rsp), %rax
        addq    64(%rsp), %rax
        movq    24(%r9), %rcx
        movb    %r8b, %dl
        negq    %rdx
        leaq    (%rdi,%rdx), %rsi
        incq    %rsi
        .p2align        4, 0x90
.LBB5_6:
        movq    %r13, %rdi
        imulq   %r12, %rdi
        addq    %rbx, %rdi
        movq    %rsi, %rdx
        xorl    %ebp, %ebp
        .p2align        4, 0x90
.LBB5_7:
        vcvtsi2sd       %rbp, %xmm2, %xmm0
        vsqrtsd %xmm0, %xmm0, %xmm0
        vmovups %xmm6, (%r15)
        movq    $0, 16(%r15)
        vmovsd  %xmm0, (%rcx)
        vaddsd  (%rax,%rdi,8), %xmm0, %xmm1
        vmovsd  %xmm1, (%rax,%rdi,8)
        vaddsd  8(%r15), %xmm0, %xmm1
        vmovsd  %xmm1, 8(%rcx)
        vaddsd  8(%rax,%rdi,8), %xmm1, %xmm1
        vmovsd  %xmm1, 8(%rax,%rdi,8)
        vaddsd  16(%r15), %xmm0, %xmm0
        vmovsd  %xmm0, 16(%rcx)
        vaddsd  16(%rax,%rdi,8), %xmm0, %xmm0
        vmovsd  %xmm0, 16(%rax,%rdi,8)
        addq    %r13, %rbp
        decq    %rdx
        testq   %rdx, %rdx
        jg      .LBB5_7
        leaq    -1(%r14), %rdx
        incq    %r13
        cmpq    $1, %r14
        movq    %rdx, %r14
        jg      .LBB5_6
        jmp     .LBB5_9
.LBB5_10:
        vxorps  %xmm0, %xmm0, %xmm0
        vmovups %xmm0, (%r15)
        movq    $0, 16(%r15)
        movabsq $numba_gil_ensure, %rax
        leaq    36(%rsp), %rcx
        callq   *%rax
        movabsq $PyErr_Clear, %rax
        callq   *%rax
        movabsq $.const.pickledata.2691858029760, %rcx
        movabsq $.const.pickledata.2691858029760.sha1, %r8
        movabsq $numba_unpickle, %rax
        movl    $180, %edx
        callq   *%rax
        testq   %rax, %rax
        je      .LBB5_11
        movabsq $numba_do_raise, %rdx
        movq    %rax, %rcx
        callq   *%rdx
.LBB5_11:
        movabsq $numba_gil_release, %rax
        leaq    36(%rsp), %rcx
        callq   *%rax
.LBB5_12:
        vmovaps 144(%rsp), %xmm6
        addq    $168, %rsp
        popq    %rbx
        popq    %rbp
        popq    %rdi
        popq    %rsi
        popq    %r12
        popq    %r13
        popq    %r14
        popq    %r15
        retq
.Lfunc_end5:

與第二部分相比,第一個(gè)版本的代碼是巨大的。總的來說,我們可以看到計(jì)算量最大的部分大致相同:

    -----  WITHOUT VIEWS  ----- 

.LBB6_6:
        imulq   %r8, %r12
        vcvtsi2sd       %r12, %xmm2, %xmm0
        vsqrtsd %xmm0, %xmm0, %xmm0
        movq    120(%rsp), %rcx
        vmovups %xmm6, (%rcx)
        movq    $0, 16(%rcx)
        movq    248(%rsp), %rdx
        vmovsd  %xmm0, (%rdx)
        vaddsd  (%rbp), %xmm0, %xmm1
        vmovsd  %xmm1, (%rbp)
        vaddsd  8(%rcx), %xmm0, %xmm1
        vmovsd  %xmm1, 8(%rdx)
        vaddsd  8(%rbp), %xmm1, %xmm1
        vmovsd  %xmm1, 8(%rbp)
        vaddsd  16(%rcx), %xmm0, %xmm0
        vmovsd  %xmm0, 16(%rdx)
        movq    %rax, %r12
        vaddsd  16(%rbp), %xmm0, %xmm0
        vmovsd  %xmm0, 16(%rbp)
        cmpb    $0, 39(%rsp)
        jne     .LBB6_7
    -----   WITH VIEWS    -----

.LBB5_7:
        vcvtsi2sd       %rbp, %xmm2, %xmm0
        vsqrtsd %xmm0, %xmm0, %xmm0
        vmovups %xmm6, (%r15)
        movq    $0, 16(%r15)
        vmovsd  %xmm0, (%rcx)
        vaddsd  (%rax,%rdi,8), %xmm0, %xmm1
        vmovsd  %xmm1, (%rax,%rdi,8)
        vaddsd  8(%r15), %xmm0, %xmm1
        vmovsd  %xmm1, 8(%rcx)
        vaddsd  8(%rax,%rdi,8), %xmm1, %xmm1
        vmovsd  %xmm1, 8(%rax,%rdi,8)
        vaddsd  16(%r15), %xmm0, %xmm0
        vmovsd  %xmm0, 16(%rcx)
        vaddsd  16(%rax,%rdi,8), %xmm0, %xmm0
        vmovsd  %xmm0, 16(%rax,%rdi,8)
        addq    %r13, %rbp
        decq    %rdx
        testq   %rdx, %rdx
        jg      .LBB5_7

雖然第一個(gè)版本的代碼比第二個(gè)版本的效率稍低,但這一差異顯然遠(yuǎn)遠(yuǎn)不足以解釋時(shí)間上的巨大差距(~65ms VS<0.6ms)。

我們還可以看到,兩個(gè)版本的匯編代碼中的函數(shù)調(diào)用不同:

    -----  WITHOUT VIEWS  ----- 

memcpy
NRT_Allocate
NRT_Free
NRT_decref
NRT_incref
NRT_MemInfo_alloc_safe_aligned
    -----   WITH VIEWS    -----

numba_do_raise
numba_gil_ensure
numba_gil_release
numba_unpickle
PyErr_Clear
NRT_decref
NRT_MemInfo_alloc_safe_aligned

NRT_Allocate、NRT_Free、NRT_decrefNRT_incref函數(shù)調(diào)用表明編譯后的代碼在熱循環(huán)的中間創(chuàng)建了一個(gè)新的Python對象,這是非常低效的。同時(shí),第二個(gè)版本不執(zhí)行任何NRT_incref,我懷疑NRT_decref實(shí)際上從未被調(diào)用過(或者可能只調(diào)用一次)。第二個(gè)代碼不執(zhí)行Numpy數(shù)組分配。看起來對PyErr_Clearnumba_do_raisenumba_unpickle的調(diào)用是為了管理可能引發(fā)的異常(但在第一個(gè)版本中并非如此,因此可能與視圖的使用有關(guān))。最后,在第一個(gè)版本中對memcpy的調(diào)用表明,新創(chuàng)建的數(shù)組確實(shí)復(fù)制到了x。分配和復(fù)制使第一個(gè)版本非常低效。

我很驚訝Numba沒有為zeros(3)生成分配。這是grea,但您應(yīng)該避免在這樣的熱循環(huán)中創(chuàng)建arrays,因?yàn)闆]有g(shù)arantee Numba。Numba將始終優(yōu)化這樣的調(diào)用。事實(shí)上,它通常不會(huì)。

您可以使用基本循環(huán)復(fù)制切片的所有項(xiàng),以避免任何分配。如果在編譯時(shí)知道切片的大小,這通常會(huì)更快。切片復(fù)制可能會(huì)更快,因?yàn)閺?fù)印機(jī)可能會(huì)更好地對代碼進(jìn)行矢量化,但在實(shí)踐中,這樣的循環(huán)相對較好auto-vectorized。

可以注意到,兩個(gè)版本的代碼中都有vsqrtsd指令,因此lambda實(shí)際上是內(nèi)聯(lián)的。

當(dāng)您將lambda從函數(shù)中移出并將其內(nèi)容放入另一個(gè)jitted函數(shù)中時(shí),LLVM可能不會(huì)內(nèi)聯(lián)該函數(shù)。您可以在生成中間表示(IR代碼)之前請求Numba手動(dòng)內(nèi)聯(lián)函數(shù),以便LLVM生成類似的代碼。這可以使用inline="always"標(biāo)志來完成。這會(huì)增加編譯時(shí)間(因?yàn)檎{(diào)用函數(shù)中的代碼接近c(diǎn)opy-pasted)。內(nèi)聯(lián)對于應(yīng)用許多進(jìn)一步的優(yōu)化(恒定傳播、SIMD矢量化、etc.)至關(guān)重要,這可能會(huì)導(dǎo)致巨大的性能提升。

国产日韩精品视频_2020久久国产最新免费观看_国内久久久久影院精品_日本一区二区视频在线

国产亚洲欧美另类中文| 欧美11—12娇小xxxx| 亚洲人成高清| 国产精品激情电影| 欧美国产一区二区| 久久本道综合色狠狠五月| 亚洲欧洲一区二区三区| 好吊色欧美一区二区三区视频| 欧美激情中文不卡| 久久蜜臀精品av| 亚洲一区免费观看| 一区二区三区高清| 亚洲日本va午夜在线影院| 狠狠久久亚洲欧美| 国产精品日韩在线| 国产精品国产亚洲精品看不卡15| 欧美激情精品久久久久久大尺度| 久久精品视频在线播放| 午夜一级在线看亚洲| 亚洲视频久久| 一本色道久久综合亚洲二区三区| 亚洲精品视频在线| 亚洲黄色影院| 亚洲乱码一区二区| 亚洲精品日韩综合观看成人91| 亚洲电影免费在线 | 久久久久综合网| 欧美在线播放一区| 久久精品国产精品亚洲| 性欧美8khd高清极品| 亚洲欧美综合一区| 久久精品99国产精品日本| 午夜伦欧美伦电影理论片| 香蕉亚洲视频| 久久激情综合网| 久久久精品免费视频| 欧美在线一二三区| 久热精品在线| 欧美精品日韩一本| 国产精品久久久999| 国产精品自拍视频| 精品96久久久久久中文字幕无| 黄色精品免费| 亚洲精品视频在线观看免费| 夜夜夜精品看看| 欧美一区二区三区在线播放| 久久久久久久一区| 欧美巨乳在线观看| 国产精品久久久久7777婷婷| 国产午夜精品全部视频播放| 激情欧美一区| 99热在这里有精品免费| 欧美一区二区免费观在线| 久久一区二区三区av| 欧美日本国产| 国产一区二区精品久久99| 亚洲精品一区二区三区福利| 在线亚洲电影| 欧美影院久久久| 欧美区国产区| 国模 一区 二区 三区| 亚洲精品激情| 久久婷婷人人澡人人喊人人爽| 欧美日本精品一区二区三区| 国产一区二区电影在线观看 | 亚洲精品视频在线观看网站| 亚洲男人的天堂在线aⅴ视频| 久久在线观看视频| 国产精品区一区二区三| 91久久在线视频| 亚欧成人在线| 国产精品成人免费| 亚洲欧洲日韩在线| 久久三级视频| 国一区二区在线观看| 亚洲综合不卡| 欧美日韩一区二区精品| 亚洲国产午夜| 久久人人九九| 国产一区二区剧情av在线| 在线视频欧美日韩精品| 欧美伦理在线观看| 91久久久一线二线三线品牌| 久久久久久久久久码影片| 国产精品va| 亚洲一区二区三区精品视频| 欧美激情一区二区久久久| 亚洲国产成人久久综合一区| 久久久久久午夜| 激情偷拍久久| 久久av红桃一区二区小说| 国产精品男女猛烈高潮激情| 亚洲图片在线观看| 国产精品porn| 亚洲综合国产| 国产欧美日本一区视频| 性欧美xxxx视频在线观看| 国产精品自在线| 亚洲欧美日韩国产中文| 国产精品你懂的| 欧美一级播放| 国产一级揄自揄精品视频| 久久国产精品久久精品国产| 激情自拍一区| 欧美国产精品久久| 日韩亚洲精品在线| 欧美午夜免费电影| 欧美一级久久久| 伊人成人在线视频| 欧美激情视频在线播放| 一二三四社区欧美黄| 国产精品成人免费| 久久精品一区二区国产| 亚洲国产精品va在线观看黑人| 蜜桃av一区二区三区| a91a精品视频在线观看| 国产精品激情偷乱一区二区∴| 香蕉国产精品偷在线观看不卡| 国产一区视频网站| 欧美连裤袜在线视频| 亚洲欧美欧美一区二区三区| 极品中文字幕一区| 欧美成人一区二区三区片免费| 亚洲午夜国产一区99re久久| 国内精品久久久| 欧美区在线播放| 欧美在线地址| 亚洲乱码国产乱码精品精天堂| 欧美日韩福利在线观看| 欧美一区二区精品在线| 亚洲国产精品久久91精品| 欧美午夜电影网| 久久综合狠狠综合久久综合88| 99精品国产在热久久| 国产精品制服诱惑| 欧美日韩国产一区二区三区| 欧美亚洲综合在线| 亚洲精品视频在线观看网站| 国产精品一区2区| 欧美激情一区二区三区| 久久成人精品| 亚洲综合精品自拍| 最新精品在线| 亚洲夫妻自拍| 国产日韩专区在线| 国产精品vvv| 欧美日韩国产综合在线| 久久综合狠狠综合久久综青草 | 国产综合av| 国产精品区一区二区三区| 欧美日韩中文在线| 欧美日本在线| 欧美日本高清一区| 欧美成人按摩| 蜜桃av噜噜一区二区三区| 久久精品亚洲精品国产欧美kt∨| 亚洲自拍偷拍色片视频| 中文欧美日韩| 亚洲天堂久久| 亚洲自拍偷拍麻豆| 午夜精品福利一区二区蜜股av| 中文国产一区| 亚洲午夜精品一区二区| 宅男精品视频| 亚洲自拍偷拍色片视频| 亚洲欧美精品在线观看| 亚洲欧美综合网| 欧美一区二区三区在线| 久久国产精品色婷婷| 久久精品视频99| 久久久久国产精品午夜一区| 久久久精品一区二区三区| 久久久久亚洲综合| 免费一级欧美片在线观看| 久久精品99国产精品酒店日本| 久久久久99| 欧美阿v一级看视频| 欧美精品色综合| 国产精品免费看| 国产视频一区在线观看| 国产在线国偷精品产拍免费yy| 国产亚洲欧美日韩美女| 亚洲高清电影| 99精品国产热久久91蜜凸| 亚洲尤物在线| 美女图片一区二区| 欧美巨乳波霸| 国产日韩精品视频一区| 在线观看欧美日韩| 99精品视频免费观看| 欧美在线一区二区| 欧美国产一区二区在线观看| 国产精品家教| 亚洲二区免费| 亚洲欧美欧美一区二区三区| 久久免费少妇高潮久久精品99| 欧美精品国产一区| 国产日韩欧美| av不卡在线看| 另类图片综合电影|