搞定剑桥面试数学题番外篇2:使用多线程并发“加强版”

news2024/11/27 0:39:02

在这里插入图片描述

0. 概览

我们在之前三篇博文中已经介绍了如何用多种语言(ruby、swift、c、x64 汇编和 ARM64 汇编)实现一道“超超超难”的剑桥数学面试题:

  • · 有趣的小实验:四种语言搞定“超超超难”剑桥面试数学题

  • · 搞定“超超超难”剑桥面试数学题番外篇:ARM64汇编

  • · 超详细:实现 Swift 与 汇编(Asm)代码混编并在真机或模拟器上运行

在以上这一系列博文中,我们用多种语言生成可执行文件,并分别在多个平台做了性能测试:

  • MacBook Pro(Intel i5 2.9GHz)
  • MacBook Air (M2)
  • iPhone XR
  • iPhone 14 Pro Max

现在,我们还想利用 cpu 强大的多核并发执行来进一步提高我们的算法速度。在本篇博文中,我们将使用 swift、c、x64汇编以及 ARM64 汇编语言来完成此“挑战”!

本文用半娱乐的心境写成,不求测试多么精确,但求保持一颗童心,Let‘s go!!!😉


1. 题目回顾

在这里插入图片描述

题目很简单:

  • 如果 a + b + c + d = 63;
  • 求 ab + bc + cd 的最大值;
  • 其中 a、b、c、d 都为自然数;

我们假设 0 不属于自然数,即有: a、b、c、d 最小值皆为 1。

2. swift 语言

我们先易后难,先让 swift 打头阵。

swift 语言是并发编程的“绝顶高手”!我们有多种“姿势”可以实现代码并发执行,这里我们使用 async/await 结构化并发来完成它。

使用 Xcode 新建控制台类型项目,并填入如下代码:

import Foundation

typealias GroupNumbers = (a: Int, b: Int, c: Int, d: Int, rlt: Int)

let full_range = 1...63
func calc_max_range(_ r: ClosedRange<Int>) async -> Int {
    var max = 0
    for a in r {
        for b in full_range {
            for c in full_range {
                for d in full_range {
                    if a + b + c + d == 63 {
                        let rlt = a*b + b*c + c*d
                        if rlt >= max {
                            max = rlt
                        }
                    }
                }
            }
        }
    }

    return max
}

let group = DispatchGroup()
group.enter()
Task {
    async let r0 = calc_max_range(1...15)
    async let r1 = calc_max_range(16...30)
    async let r2 = calc_max_range(31...45)
    async let r3 = calc_max_range(46...63)
    
    let max = await [r0, r1, r2, r3].max()!
    print("max is \(max)")
    group.leave()
}

group.wait()

使用 Release 配置编译运行,在 M2 上大约耗时 0.017 秒左右。

3. c 语言

c 语言并发编程远比想象的要简单的多,我们可以利用 pthread 库非常容易的把指令流调度到多核上:

#include <stdio.h>
#include <pthread.h>

const int START = 1;
const int END = 63;

typedef struct {
    pthread_t id;
    int start, end;
    int max;
} PInfo;

void *calc_range(void *args) {
    int max = 0;
    PInfo* info = (PInfo *) args;

    for (int a = info->start; a <= info->end; a++) {
        for (int b = START; b <= END; b++) {
            for (int c = START; c <= END; c++) {
                for (int d = START; d < END; d++) {
                    if(a + b + c + d == 63) {
                        int rlt = a*b + b*c + c*d;
                        if(rlt >= max) {
                            max = rlt;
                        }
                    }
                }
            }
        }
    }

    info->max = max;
    pthread_exit(NULL);
}

int main() {

    PInfo infos[4] = {
        {NULL, 1, 15, 0},
        {NULL, 16, 30, 0},
        {NULL, 31, 45, 0},
        {NULL, 46, END, 0}
    };

    pthread_create(&infos[0].id, NULL, calc_range, &infos[0]);
    pthread_create(&infos[1].id, NULL, calc_range, &infos[1]);
    pthread_create(&infos[2].id, NULL, calc_range, &infos[2]);
    pthread_create(&infos[3].id, NULL, calc_range, &infos[3]);

    int max = 0;
    for (int i = 0; i < 4; i++) {
        pthread_join(infos[i].id, NULL);
        if(infos[i].max > max) {
            max = infos[i].max;
        }
    }

    printf("max is %d\n", max);
    return 0;
}

因为上面 4 个线程写入结果的地址都不相同,所以不会有数据竞争发生。

使用 O2 选项优化编译代码,同样在 M2 mac 上运行平均耗时 0.015 秒,比 swift 有所进步。

4. x64 汇编

x64 汇编相比较 swift 和 c 两种语言,更显“繁琐”一些。

不过核心思路仍然很简单:我们只需调用系统 fork 功能号创建新线程,并发计算即可。

但是,这样要处理的底层事情太多,不如借助 c 库(pthread)更简单!

# as mt_x64.s -o mt_x64.o
# ld mt_x64.o -lSystem -L `xcrun --show-sdk-path -sdk macosx`/usr/lib -o mt_x64  

.equ    loop_upper_bound, 63
.equ    NULL,0
// PINFO 结构的长度
.equ    PINFO_SIZE, pinfo_1 - pinfo_0

// 函数构造器
.macro  func_constructor
    push    %rbp
    mov     %rsp,%rbp
    pushq   %rbx
    pushq   %rdx
.endm

// 函数析构器
.macro  func_destructor
    popq    %rdx
    popq    %rbx
    popq    %rbp
.endm
    
    .data
pinfo_0:
    // pthread_t, start, end, max
    .quad NULL,1,15,0
pinfo_1:
    .quad NULL,16,30,0
pinfo_2:
    .quad NULL,31,45,0
pinfo_3:
    .quad NULL,46,loop_upper_bound,0
max:
    .quad 0
string: .asciz  "max is %ld\n"
    .text
    .globl      _main
    .p2align    4, 0x90
_main:
    func_constructor
    
    leaq    pinfo_0(%rip),%rdi
    movq    $0,%rsi
    leaq    calc_max_in_range_func(%rip),%rdx
    movq    %rdi,%rcx
   	// pthread_create(rdi,rsi,rdx,rcx)
    call    _pthread_create

    leaq    pinfo_1(%rip),%rdi
    movq    $0,%rsi
    leaq    calc_max_in_range_func(%rip),%rdx
    movq    %rdi,%rcx
    call    _pthread_create

    leaq    pinfo_2(%rip),%rdi
    movq    $0,%rsi
    leaq    calc_max_in_range_func(%rip),%rdx
    movq    %rdi,%rcx
    call    _pthread_create

    leaq    pinfo_3(%rip),%rdi
    movq    $0,%rsi
    leaq    calc_max_in_range_func(%rip),%rdx
    movq    %rdi,%rcx
    call    _pthread_create

    movq    pinfo_0(%rip),%rdi
    xorq    %rsi,%rsi
    // pthread_join(rdi,rsi)
    call    _pthread_join

    movq    pinfo_1(%rip),%rdi
    xorq    %rsi,%rsi
    call    _pthread_join

    movq    pinfo_2(%rip),%rdi
    xorq    %rsi,%rsi
    call    _pthread_join

    movq    pinfo_3(%rip),%rdi
    xorq    %rsi,%rsi
    call    _pthread_join

    // i in rax, pinfo addr in rbx, max in r11
    movq    $3,%rax
    leaq    pinfo_0(%rip),%rbx
    mov     24(%rbx),%r11
1:
    addq    $PINFO_SIZE,%rbx
    mov     24(%rbx),%r12
    cmpq    %r12,%r11
    jg      2f
    mov     %r12,%r11
2:
    dec     %rax
    jz      3f
    jmp     1b
3:
    movq    %r11,%rsi
    lea     string(%rip),%rdi
    callq   _printf
    func_destructor
    xor     %rax,%rax
    ret
.pushsection "__TEXT", "__text"
// void *calc_max_in_range(void *arg);
calc_max_in_range_func:
    func_constructor

    // void *arg in %rdi
    // rax: start, r12: a loop end
    movq    8(%rdi),%rax
    movq    16(%rdi),%r12
    mov     $1,%rbx
    mov     %rbx,%rcx
    mov     %rbx,%rdx
    // max in r11
    xor     %r11,%r11
start_a_loop:
    cmpq    %r12,%rax
    jg      end_a_loop
start_b_loop: 
    cmpq    $loop_upper_bound,%rbx
    jg      end_b_loop
start_c_loop:
    cmpq    $loop_upper_bound,%rcx
    jg      end_c_loop
start_d_loop:
    cmpq    $loop_upper_bound,%rdx
    jg      end_d_loop

    # if a + b + c + d == 63
    xorq    %r8,%r8
    add     %rax,%r8
    add     %rbx,%r8
    add     %rcx,%r8
    add     %rdx,%r8
    cmpq    $loop_upper_bound,%r8
    jne     not_equ_63
    # == 63, 计算 a*b + b*c + c*d 放到 r8 中
    mov     %rax,%r8
    imul    %rbx,%r8
    
    mov     %r8,%r9
    mov     %rbx,%r8
    imul    %rcx,%r8
    
    mov     %r8,%r10
    mov     %rcx,%r8
    imul    %rdx,%r8
    
    addq    %r9,%r8
    addq    %r10,%r8
    cmpq    %r11,%r8
    jl      not_equ_63

    # 更新 max 值
    mov     %r8,%r11
not_equ_63:
    incq    %rdx
    jmp     start_d_loop
end_d_loop:
    mov     $1,%rdx
    incq    %rcx
    jmp     start_c_loop
end_c_loop:
    mov     $1,%rcx
    incq    %rbx
    jmp     start_b_loop
end_b_loop:
    mov     $1,%rbx
    incq    %rax
    jmp     start_a_loop
end_a_loop:
    mov     %r11,24(%rdi)
    func_destructor
    xorq    %rax,%rax
    ret
.popsection

咋一看上面代码很长,但其本质很简单,我们在关键处做了注释,方便大家阅览。

使用调试器加载运行 x64 汇编代码生成的可执行文件,在第一个 pthread_join 函数下断点,中断后可以发现我们的计算确是在多个线程上并发进行的:

在这里插入图片描述

汇编代码在 MBP(intel i5)上大约耗时 0.025 秒。


我们可以在  Silicon 芯片的 mac 上使用交叉编译来处理上述 x64 汇编代码,然后利用 Rosetta 2 来运行它:

// 使用 x86_64 架构编译代码
as x64.s -arch x86_64 -o x64.o
ld x64.o -lSystem -L `xcrun --show-sdk-path -sdk macosx`/usr/lib -o x64    

运行发现耗时仅 0.023 秒左右,在 M2 上翻译执行的速度反而要比在 intel cpu 上原生执行还要快,只能说那台 intel MBP “廉颇老矣”…

为了证明上面 x64 汇编产生的可执行文件的确是 intel x64 指令集,我们可以用 otool 工具来验证一下:

hopy@Love2 asm % otool -tvV x64
x64:
(__TEXT,__text) section
_main:
0000000100003de0	pushq	%rbp
0000000100003de1	movq	%rsp, %rbp
0000000100003de4	pushq	%rbx
0000000100003de5	pushq	%rdx
0000000100003de6	leaq	pinfo_0(%rip), %rdi
0000000100003ded	movq	$NULL, %rsi
0000000100003df4	leaq	calc_max_in_range_func(%rip), %rdx
0000000100003dfb	movq	%rdi, %rcx
0000000100003dfe	callq	0x100003edc                     ## symbol stub for: _pthread_create
0000000100003e03	leaq	pinfo_1(%rip), %rdi
0000000100003e0a	movq	$NULL, %rsi
0000000100003e11	leaq	calc_max_in_range_func(%rip), %rdx
0000000100003e18	movq	%rdi, %rcx
0000000100003e1b	callq	0x100003edc                     ## symbol stub for: _pthread_create
0000000100003e20	leaq	pinfo_2(%rip), %rdi
0000000100003e27	movq	$NULL, %rsi
0000000100003e2e	leaq	calc_max_in_range_func(%rip), %rdx
0000000100003e35	movq	%rdi, %rcx
0000000100003e38	callq	0x100003edc                     ## symbol stub for: _pthread_create
0000000100003e3d	leaq	pinfo_3(%rip), %rdi
0000000100003e44	movq	$NULL, %rsi
0000000100003e4b	leaq	calc_max_in_range_func(%rip), %rdx
0000000100003e52	movq	%rdi, %rcx
0000000100003e55	callq	0x100003edc                     ## symbol stub for: _pthread_create
0000000100003e5a	movq	pinfo_0(%rip), %rdi
0000000100003e61	xorq	%rsi, %rsi
0000000100003e64	callq	0x100003ee2                     ## symbol stub for: _pthread_join
0000000100003e69	movq	pinfo_1(%rip), %rdi
0000000100003e70	xorq	%rsi, %rsi
0000000100003e73	callq	0x100003ee2                     ## symbol stub for: _pthread_join
0000000100003e78	movq	pinfo_2(%rip), %rdi
0000000100003e7f	xorq	%rsi, %rsi
0000000100003e82	callq	0x100003ee2                     ## symbol stub for: _pthread_join
0000000100003e87	movq	pinfo_3(%rip), %rdi
0000000100003e8e	xorq	%rsi, %rsi
0000000100003e91	callq	0x100003ee2                     ## symbol stub for: _pthread_join
0000000100003e96	movq	$0x3, %rax
0000000100003e9d	leaq	pinfo_0(%rip), %rbx
0000000100003ea4	movq	0x18(%rbx), %r11
0000000100003ea8	addq	$0x20, %rbx
0000000100003eac	movq	0x18(%rbx), %r12
0000000100003eb0	cmpq	%r12, %r11
0000000100003eb3	jg	0x100003eb8
0000000100003eb5	movq	%r12, %r11
0000000100003eb8	decq	%rax
0000000100003ebb	je	0x100003ebf
0000000100003ebd	jmp	0x100003ea8
0000000100003ebf	movq	%r11, %rsi
0000000100003ec2	leaq	string(%rip), %rdi
0000000100003ec9	callq	0x100003ed6                     ## symbol stub for: _printf
0000000100003ece	popq	%rdx
0000000100003ecf	popq	%rbx
0000000100003ed0	popq	%rbp
0000000100003ed1	xorq	%rax, %rax
0000000100003ed4	retq

看到了吗?百分之百纯正 intel x64 指令!😉


5. ARM64 汇编

现在,让最后一位选手 ARM64 登场吧。

ARM64 和 x64 汇编都可以用 as 汇编器(Mac OS X Mach-O GNU-based assemblers)编译成目标文件。我们还可以利用 as 的 arch 选项实现跨平台交叉编译。

比如,我们在 intel Mac 上可以利用如下命令编译 ARM64 格式的汇编代码:

as test_arm64.s -arch arm64 -o arm64.o

类似的,前面我们也讨论过如何在 M2 Mac 上编译执行 x64 汇编代码。

下面,我们就用 ARM64 汇编代码实现多线程并发计算:

# as mt_arm64.s -o mt_arm64.o
# ld mt_arm64.o -lSystem -L `xcrun --show-sdk-path -sdk macosx`/usr/lib -o mt_arm64
# mt_arm64.s

.equ    loop_upper_bound, 63
.equ    NULL,0

// 函数构造器
.macro  func_constructor
    sub     sp,sp,#32
    stp     x29,x30,[sp,#16]
    add     x29,sp,#16
.endm

// 函数析构器
.macro  func_destructor
    ldp     x29,x30,[sp,#16]
    add     sp,sp,#32
.endm
    
    .data
pinfo_0:
    // pthread_t, start, end, max
    .quad NULL,1,15,0
pinfo_1:
    .quad NULL,16,30,0
pinfo_2:
    .quad NULL,31,45,0
pinfo_3:
    .quad NULL,46,loop_upper_bound,0

    .text
    .globl  _main
    .p2align    2
// *******************************************************************
_main:
    func_constructor

    adrp    x0,pinfo_0@PAGE
    add     x0,x0,pinfo_0@PAGEOFF
    mov     x19,x0

    mov     x1,#0
    adr     x2,_calc_max_thread_func
    mov     x3,x19
    bl      _pthread_create

    add     x5,x19,#32
    mov     x0,x5
    mov     x1,#0
    adr     x2,_calc_max_thread_func
    mov     x3,x5
    bl      _pthread_create

    add     x5,x19,#64
    mov     x0,x5
    mov     x1,#0
    adr     x2,_calc_max_thread_func
    mov     x3,x5
    bl      _pthread_create

    add     x5,x19,#96
    mov     x0,x5
    mov     x1,#0
    adr     x2,_calc_max_thread_func
    mov     x3,x5
    bl      _pthread_create

    ldr     x0,[x19]
    mov     x1,xzr
    bl      _pthread_join

    add     x5,x19,#32
    ldr     x0,[x5]
    mov     x1,xzr
    bl      _pthread_join

    add     x5,x19,#64
    ldr     x0,[x5]
    mov     x1,xzr
    bl      _pthread_join

    add     x5,x19,#96
    ldr     x0,[x5]
    mov     x1,xzr
    bl      _pthread_join

    mov     x11,xzr
    mov     x0,4
0:
    ldr     x1,[x19,24]
    cmp     x11,x1
    b.ge    1f
    mov     x11,x1
1:
    subs    x0,x0,1
    b.eq    2f
    add     x19,x19,#32
    b       0b
2:
    adr     x0,string
    str     x11,[sp]
    bl      _printf

    func_destructor
    mov     x0,xzr
    ret
// *******************************************************************
// void *calc_max_thread_func(void *arg)
_calc_max_thread_func:
    func_constructor
    str     x0,[x29,#-8]

    mov     x12,x0
    ldr     x0,[x12,#8]
    ldr     x1,[x12,#16]
    bl      _calc_max_in_range

    ldr     x12,[x29,#-8]
    str     x0,[x12,#24]

    func_destructor
    mov     x0,NULL
    ret
// *******************************************************************
.pushsection "__TEXT", "__text"
// long calc_max_in_range(long start, long end);
_calc_max_in_range:
    func_constructor
    // start in x0, end in x1
    mov     x12,x1  // a loop end in x12
    mov     x1,#1   // b in x1
    mov     x2,x1   // c in x2
    mov     x3,x1   // d in x3
    mov     x11,xzr // max in x11
1:
    cmp     x0,x12
    b.hi    9f
2:
    cmp     x1,loop_upper_bound
    b.hi    8f
3:
    cmp     x2,loop_upper_bound
    b.hi    7f
4:
    cmp     x3,loop_upper_bound
    b.hi    6f
    // 计算 a + b + c + d 的值
    add     x4,x0,x1
    add     x4,x4,x2
    add     x4,x4,x3
    cmp     x4,loop_upper_bound
    b.ne    5f
    // 若等于 a + b + c + d = 63,则计算 ab + bc + cd 的值 x
    mul     x4,x0,x1
    mul     x5,x1,x2
    mul     x6,x2,x3
    add     x5,x5,x6
    add     x4,x4,x5
    // 若 x > max ,则需要更新 max 为 x 值
    cmp     x4,x11
    b.ls    5f
    mov     x11,x4
5:
    add     x3,x3,#1
    b       4b
6:
    mov     x3,#1
    add     x2,x2,#1
    b       3b
7:
    mov     x2,#1
    add     x1,x1,#1
    b       2b
8:
    mov     x1,#1
    add     x0,x0,#1
    b       1b
9:
    func_destructor
    mov     x0,x11
    ret
.popsection
string: .asciz  "max is %ld\n"

如上所示:ARM64 汇编语言的数据格式和 x64 汇编没有什么差别,不过指令语法、函数构造器和析构器等还是有很大不同的。

将上述代码编译链接为可执行文件,在 M2 MBA 上运行耗时大约在 0.015 秒左右,和 c 旗鼓相当。

之前在 M2 上单线程执行算法耗时将近 0.03 秒之多,现在快了 1 倍!可见  Silicon 芯片上多核并发执行就是“香”啊!

值得一提的是,因为  的A系列处理器(比如 iPhone14 Pro Max 的 A16)同样兼容 ARM64 指令集,所以上述代码同样可以运行在 iPhone 真机上。

6. 总结

在本篇博文中,我们使用并行算法(swift、c、x64汇编和 ARM64 汇编)充分“榨干” 了 cpu ,进一步提高了原算法的速度,棒棒哒!

感谢观赏,再会!😎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/651154.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【每日挠头算法题(7)】对称的二叉树|二叉树的所有路径

欢迎&#xff01; 前言一、对称的二叉树思路&#xff1a;递归法具体代码如下&#xff1a; 二、二叉树的所有路径思路&#xff1a;递归法具体代码如下&#xff1a; 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#xff1a;随着人工智能的不…

如何快速选择合适的会计软件?这些推荐值得尝试!

现今&#xff0c;许多公司都在使用会计软件来管理它们的财务&#xff0c;提高工作效率。因此选择一个适合自己公司的会计软件是相当重要的。但是&#xff0c;对于许多小型企业而言&#xff0c;如何选择最适合自己的会计软件并不容易。那么&#xff0c;该如何选择合适的会计软件…

开启跨平台之旅:学习Flutter,掌握移动应用开发的未来

Flutter是一种开源的移动应用开发框架&#xff0c;由Google开发和维护。它使用Dart语言进行编写&#xff0c;并提供了丰富的UI组件和工具&#xff0c;用于构建高性能、跨平台的移动应用程序。 优势 跨平台开发&#xff1a;Flutter是一种跨平台的移动应用开发框架&#xff0c;…

管理类联考——英语——技巧篇——时态表

一般现在时 1.概念&#xff1a;经常、反复发生的动作或行为及现在的某种状况。 2.基本结构&#xff1a;①is/am/are;②do/does否定形式&#xff1a;①am/is/are not;②此时态的谓语动词若为行为动词&#xff0c;则在其前加don‘t&#xff0c;如主语为第三人称单数&#xff0c…

资深测试总结,性能测试-业务量/吞吐量/存量数据设计关联(详细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 业务量 是不带时…

HTML | html文档中html和body标签的默认尺寸是多少?

新建一个空白的html文件&#xff0c;如下&#xff1a; <!DOCTYPE html> <html lang"en"><head><title></title><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-sc…

day56|动态规划16-编辑距离问题

583. 两个字符串的删除操作 明确dp数组的含义&#xff1a; dp[i][j] 以i-1为结尾的word1和以j-1为结尾的word2&#xff0c;为相同的最小操作次数递归函数&#xff1a; if word1[i-1] word1[j-1]: dp[i][j] dp[i-1][j-1] # 不需要删除&#xff0c;只看上一层的字符串即可 else…

阿里云如何帮助企业进行数据迁移和数据同步?有哪些应用案例?

阿里云如何帮助企业进行数据迁移和数据同步&#xff1f;有哪些应用案例&#xff1f; [本文由阿里云代理商[聚搜云www.4526.cn]撰写] 阿里云数据迁移与数据同步解决方案 阿里云为企业提供了一系列高效、安全并应对不同场景需求的数据迁移与同步服务。这些服务旨在最大范围减少企…

Seata学习 @GlobalTransactional注解的作用

Seata学习 GlobalTransactional注解的作用 1.自动配置类 SeataAutoConfiguration 引入 seata与SpringBoot的整合包后&#xff0c;基于SpringBoot的自动配置&#xff0c;会往Spring容器中自动添加 SeataAutoConfiguration 而 SeataAutoConfiguration 配置类又会往容器中添加be…

基于Java汽车客运站管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…

TrafficRoute:一体化的DNS解析和流量调度套件

TrafficRoute是火山引擎推出的解析调度套件&#xff0c;它实现了“一体化”的解析和调度服务&#xff0c;覆盖「公网解析」、「私网解析」、「流量调度/容灾」等场景&#xff0c;提供高性能、高可用、精准、及时、安全和可定制的解析调度产品集。 TrafficRoute具备云解析 DNS、…

华为OD机试真题 JavaScript 实现【字符串通配符】【2022Q4 200分】

一、题目描述 问题描述&#xff1a;在计算机中&#xff0c;通配符一种特殊语法&#xff0c;广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。 要求&#xff1a; 实现如下2个通配符&#xff1a; &#xff1a;匹配0个或以上的字符&#xf…

【一文解决】已安装CUDA与Pytorch但torch.cuda.is_available()为False

目录 问题描述总览&#xff1a;导致问题的原因可能1&#xff1a;CUDA版本与驱动程序不兼容可能2&#xff1a;CUDA库的路径设置存在问题可能3&#xff1a;PyTorch版本与CUDA版本不匹配可能4&#xff1a;编译问题可能5&#xff1a;软件包或库冲突写在最后 问题描述 已经安装CUDA…

2023 陕西省大学生网络安全技能大赛 --- 高职组 Crypto ezmath

文章目录 题目解题过程 题目 from Crypto.Util.number import * from secret import y,a,b flagbflag{} l len(flag) m1, m2 flag[: l // 2], flag[l // 2:]x bytes_to_long(m1) c bytes_to_long(m2)assert (x**21)*(y**21)-2*(xy)*(x*y1)gift-4*x*y 4*b**6-2*a**33*a*c …

JavaScript案例分享:让前端开发者抓狂的按钮

前言 我分享一个前端案例&#xff0c;代码来源我不确定&#xff0c;可能是我某个编程技术交流群的群友分享的。由于我设置了自动下载文件&#xff0c;今天在查看微信文件时偶然发现了这个案例&#xff0c;查看下载日期是6月7日&#xff0c;所以无法确定到底是哪个群友分享的。但…

618,你会入手哪些书?【文末送书】

好书分享 前沿技术人工智能半导体新一代通信与信息技术网络空间安全参与规则 一年一度的618又到啦&#xff01;今年的618就不要乱买啦&#xff0c;衣服买多了会被淘汰&#xff0c;电子产品买多了会过时&#xff0c;零食买多了会增肥&#xff0c;最后怎么看都不划算。可是如果你…

超强整理,性能测试-常用服务器性能指标分析总结,一篇概全...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 压测过程中&#…

Hive SQL DML

Hive SQL DML 本节所需数据集 数据集 提取码&#xff1a;rkun ⛵加载数据 Load 加载&#xff0c;装载将数据文件移动到与Hive表对应位置&#xff0c;移动时是纯复制&#xff0c;移动操作。纯复制移动指数据load加载到表中&#xff0c;hive不会对表中数据内容进行任何变换&…

Cache技术在星辰处理器中的应用

Cache技术在星辰处理器中的应用-修复MicroPython在MM32F5上启动慢的问题 文章目录 Cache技术在星辰处理器中的应用-修复MicroPython在MM32F5上启动慢的问题引言Cache的工作原理需要关闭DCache的情况鱼和熊掌都想要使用内存保护单元MPU使用内存隔离/同步指令 总结参考文献 引言 …

catkin cmake官方教程解读以及资料补充

这里写目录标题 cmakei下载cmake 官方教程教程1step1最低版本 报错报错2 vscode 路径没有配置好setting.json通过该方式打开的似乎是一个全局的文件&#xff0c;可以为本工作文件夹下设置一个本地的吗 报错3配置cmake工具链准确的流程报错4 cpp中main函数返回值问题结果 官方教…