高性能计算应用优化之运行参数优化

news2024/9/27 21:22:04

程序运行时系统的各项配置一般是按照普适性原则,尽可能满足大多数场景下的需求,并未针对特定场景进行优化,这虽然能够提高环境的通用性,但限制了性能提高的空间。运行时参数可以根据用户的需求来调整程序的运行方式和资源分配,从而提高应用程序的性能。

根据程序运行的过程,可以依次在进程布局,通信方法,内存分配多个方面进行优化。通过调整运行时参数,用户可以控制进程在NUMA上的排布,避免不合理的跨NUMA访问;可以用于控制程序运行前预加载的动态库,通过预加载动态库的方式改变所使用的内存分配库;控制MPI等通信库的行为,改变通信库所使用的算法等。

运行参数调优--NUMA

NUMA 非一致性内存访问,不同的内存器件和CPU核心从属不同的 node。

优点:扩展性好,访问本地快

缺点:访问远端慢

numactl工具可用于查看当前服务器的NUMA节点配置、状态,可通过该工具将进程绑定到指定CPU核上,由指定CPU核来运行对应进程。

不同NUMA内的CPU核访问同一个位置的内存,性能不同。在应用程序运行时要尽可能地避免跨NUMA访问内存,可以通过numactl启动程序。

如下面的启动命令表示启动程序./test,test就只能在CPU core 0到core7运行(-C控制)。

numactl -C 0-7 ./process

将 process 运行在 node0,并从 node0、node1 申请内存

numactl --cpunodebind=0 --membind=0,1 process

 将 process 运行在 node0,并从 node0、node1 申请内存 balancing

numactl --cpunodebind=0 --balancing --membind=0,1 ./process

numstat命令主要是显示进程与每个numa节点的内存分配的统计数据和分配的成功与失败情况,可以通过numastat命令查看绑核前后numa_hit和numa_miss的差异。

运行参数调优--预加载库

系统在运行过程中,会首先加载LD_PRELOAD指定的函数库(在libc.so之前),如果函数库内包含了程序中执行的函数名,该可执行文件的函数将被重定向到LD_PRELOAD指向的函数中。

使用特定的malloc库替换默认的内存分配库,以提高内存分配的效率。例如,使用intel的qkmalloc,它提供了以下几个函数的替代:

void* malloc(size_t size)void free(void* ptr)void* calloc(size_t nobj, size_t size)void* realloc(void* ptr, size_t size)

在使用时需要设置环境变量 

LD_PRELOAD=/usr/lib/libqkmalloc.so

除此之外业界常见的库包括:ptmalloc(glibc标配)、tcmalloc(google)、jemalloc(facebook)。在不同场景下的优劣势不同。在此不再详述。但预加载方式相同。

运行参数调优--OpenMP参数

同一进程内的所有 OpenMP 线程共享地址空间,因此容易受到 NUMA 效应的影响。尤其是访存密集的负载在线程数超过单个 NUMA domain 的核心数时,很可能产生性能下降。因此,线程数并非越多越好,编写程序时也需要考虑到此影响。

OpenMP 进程使用以下的方式控制线程的绑定:

OMP_PROC_BIND 环境变量:控制线程绑定与否,以及线程对于绑定单元(称为 place)分布。该变量可以取以下值:

  • true:线程不能被移动

  • false:线程可以被移动

  • master:worker线程与master线程在同一个分区

  • close:worker线程在连续分区中靠近master线程,例如,如果master线程占用硬件线程0,则worker线程1将放在硬件线程1上,worker线程2放在硬件线程2上,依此类推

  • spread:worker线程分布在可用的位置上,以最大化两个相邻线程之间的空间

OMP_PLACES 环境变量:OMP_PLACES用于指定机器上放置线程的位置。然而,该变量本身并不能完全确定线程固定,因为系统仍然不知道以何种模式将线程分配给给定的位置。因此,还需要设置OMP_PROC_BIND。常用 threads/cores/sockets,threads表示一个place是单个硬件线程,即超线程将被忽略,cores表示一个place是具有相应数量的硬件线程的单个核心,sockets表示一个place就是一个socket。

示例如下:

OMP_NUM_THREADS=28 OMP_PROC_BIND=true OMP_PLACES=cores:

每个线程绑定到一个 core,使用默认的分布(线程 n 绑定到 core n);

OMP_NUM_THREADS=2 OMP_PROC_BIND=true OMP_PLACES=sockets

每个线程绑定到一个 socket;

OMP_NUM_THREADS=4 OMP_PROC_BIND=close OMP_PLACES=cores

每个线程绑定到一个 core,线程在 socket 上连续分布(分别绑定到 core 0,1,2,3;

OMP_NUM_THREADS=4 OMP_PROC_BIND=spread OMP_PLACES=cores

每个线程绑定到一个 core,线程在 socket 上尽量散开分布(分别绑定到 core 0,7,14,21;

在使用 MPI + OpenMP 混合编程时,进程绑定对性能的影响尤为关键。每个 MPI 进程需要绑定在一组核心上(通常属于同一个 NUMA domain),并把它的 OpenMP 线程绑定在其中的每个核心上。如使用 2 进程×14 线程的绑定方式为:

OMP_NUM_THREADS=14 OMP_PROC_BIND=true OMP_PLACES=cores srun -n 2 -N 1 --cpu-bind=sockets ./exe

英特尔运行时库同样能够将OpenMP*线程绑定到物理处理单元。该接口是使用KMP_AFFINITY环境变量控制的。使用KMP_AFFINITY环境变量控制线程绑定。根据系统(机器)拓扑结构、应用程序和操作系统的不同,线程关联性可能对应用程序速度产生显著影响。

KMP_AFFINITY=[<modifier>,...]<type>[,<permute>][,<offset>]

  • type = none (default):不绑定线程; 

  • type = balanced:线程放置在单独的核心上;•type = compact:将线程+1接近线程<n>;

  • type = disabled:完全禁用线程关联接口; 

  • type = explicit:将OpenMP线程分配给使用proclist=modifier显式指定的核心ID列表; 

  • type = scatter:将线程均匀分布在整个系统中。

  • modifier = granularity=:

  • core:绑定到内核的线程在不同的线程上下文之间浮动。

  • fine/thread:每个线程绑定到单个线程上下文。

  • tile/die/node/group/socket:允许绑定到tile、die、NUMA节点、组或套接字的所有线程其中的不同线程上下文之间浮动。

运行参数调优--进程绑定

进程绑定,即让某一个进程固定在某个CPU核上,可以避免进程在CPU 核之间切换带来的开销,可以减轻cache 争抢现象。特别是当进程数为CPU 总核数一半左右时,有时会发现测试结果不稳定,时好时坏,很可能是因为进程切换造成的,这时不妨尝试进行进程CPU 绑定。

Intel MPI进程映射与绑定

I_MPI_PIN=<arg>。以下取值表示开启绑定:enable,yes,on,1;以下取值表示关闭绑定:disable,no,off,0。

I_MPI_PIN_PROCESSOR_LIST=<list>。该列表定义处理器子集和MPI进程的映射规则。此环境变量既适用于英特尔微处理器,也适用于非英特尔微处理器,但与非英特尔微处理器相比,它可能会对英特尔微处理器执行额外的优化。

I_MPI_PIN_PROCESSOR_LIST=<proclist>。其中proclist为逻辑处理器编号和/或处理器范围的逗号分隔列表。编号为i的进程固定到列表中的第i个处理器。

I_MPI_PIN_PROCESSOR_LIST=P0, P1, P2,..., Pn

I_MPI_PIN_PROCESSOR_LIST=[<procset>][:[grain=][,shift=][,preoffset=<preoffset>][,postoffset=<postoffset>]

grain = 2,shift = 3 grains,offset = 0

此方法提供定义的处理器组(grain)沿处理器列表的循环移位,步长等于shift*grain,并在末尾的offset*grain上进行单次移位。

I_MPI_PIN_PROCESSOR_LIST=[<procset>][:map=<map>]

  • bunch:进程按比例映射到尽可能靠近的socket。

  • scatter:进程被尽可能远程映射,以避免共享公共资源

  • spread:进程被连续映射,并且可能不共享公共资源

图中有两个socket,每个socket有四个核心,每个核心有一个逻辑CPU,并且每个共享缓存有两个核心。

I_MPI_PIN_DOMAIN:定义节点上逻辑处理器的多个非重叠子集,每个子集一个MPI进程。

  • =<mc-shape>::core/socket/numa/node/cache1/cache2/cache3/cache

  • =<size>[:<layout>]:

    size(omp/auto/n);layout(platform/compact/scatter)

例如:当执行以下命令时,根据socket的数量定义了两个域。进程0可以在第0个socket上的所有内核上迁移。进程1可以在第1个socket上的所有内核上迁移。

mpirun -n 2 -env I_MPI_PIN_DOMAIN socket ./a.out

I_MPI_PIN_ORDER=<order>:定义MPI进程到域的映射顺序

  • range:根据处理器的BIOS编号排序的。

  • scatter:使相邻域的公共资源共享最小化。

  • compact:使相邻域尽可能多地共享公共资源。

  • spread:连续排序的,有可能不共享公共资源。

  • bunch:进程按比例映射到socket,尽可能靠近。

例如:

I_MPI_PIN_DOMAIN=2 I_MPI_PIN_ORDER=compact

则分布如下。

OpenMPI进程映射与绑定

进程映射参数:

使用OpenMPI绑定进程,将进程映射到指定的对象,默认是core。支持的选项包括slot、hwthread、core、l1cache、l2cache、l3cache、package、numa和none。

  • mpirun --map-by slot:pe=n:将n个处理核心绑定到每个进程上

  • mpirun --map-by slot:span:根据slot负载均衡为程序分配进程

  • mpirun --nolocal:不要在运行orterun的同一节点上启动进程

  • mpirun --cpu-list:在指定的逻辑CPU列表的核心上启动进程

使用示例:

mpirun -np 16 --map-by ppr:1:l3cache:pe=4 …

假设节点的总核心数是64个,共计跑了16个进程。通过hwloc-ls 查看节点有16个L3cache,此处按照l3cache 来分配资源,总核心数是64个,共计16个L3cache,则每个L3cache包含4个核心,则将pe设置成4就可以把所有核心跑满

进程绑定参数:

进程绑定是将进程绑定到指定的对象,默认是core。支持的选项包括slot、hwthread、core、l1cache、l2cache、l3cache、package、numa和none。

  • mpirun --bind-to core:将进程绑定到核心上。

  • mpirun --bind-to socket:将每个进程绑定到CPU槽位上

  • mpirun --report-bindings:报告已启动进程的任何绑定

使用示例:

mpirun  --allow-run-as-root --hostfile hostfile   --report-bindings  --bind-to core  hostname

运行参数调优--MPI参数

Intel MPI参数

Intel MPI可以设置I_MPI_ADJUST_<opname>环境变量以在特定条件下为集合操作选择所需的算法。每个集合操作都有自己的环境变量和可选择的算法。在集合通信性能不佳时,根据机器特性和数据包大小特征调整集合通信所使用的算法可能能够提高性能。

具体语法为:

I_MPI_ADJUST_<opname>="<presetid>"[:<conditions>][;<presetid>:<conditions>[...]]"

下表列举了常用的集合算法及其相关的环境变量和所支持的算法,更多集合通信算法请参阅Intel MPI 手册。

例如,在Allgather算法中,较常使用的为Bruck’s算法或Recursive Doubling算法。

I_MPI_COLL_INTRANODE:切换集合操作中的节点内部进程的通信类型,有两个可选值,pt2pt仅使用基于点对点通信的集合通信,shm启用共享内存集合通信。

I_MPI_COLL_EXTERNAL:enable/1/yes使用可用的外部集合通信操作库;disable/0/no禁用外部集合通信操作库;hcoll使用hcoll通信库。

I_MPI_FABRICS:选择要使用的特定FABRICS,可以选择ofi或shm:ofi或shm。

I_MPI_SHM:根据体系结构和指令集选择要使用的共享内存传输。可选的值有:bdw_sse、bdw_avx2、skx_sse、skx_avx2、skx_avx512、clx_sse、clx_avx2、clx_avx512、clx-ap、icx。

I_MPI_MALLOC:控制MPI库专用内存的分配器。

I_MPI_EXTRA_FILESYSTEM:控制对并行文件系统的支持,该选项虽然能够在特定场景下优化特定文件系统的性能,但可能导致死锁。

运行参数调优--UCX参数

UCX 是一个高性能网络通信库,它作为 MPI 所依赖的通信模块之一在高性能计算领域得到广泛的使用。UCX 使用 C 语言编写,提供高效且相对简单的方法来构建广泛使用的 HPC 协议。UCX框架主要由3个组件组成,即UCS、UCT和 UCP。底层的UCT适配各种通信设备,上层的UCP则是在UCT不同设备的基础上封装更抽象的通信接口,UCT是传输层,抽象了各种硬件架构之间的差异。

以下是一些常用的参数,更多参数请参见UCX文档。

UCX_TLS可用于调整MPI使用的通信协议。可设置的参数包括shm,rc,ud,rc_x,ud_x,dc_x等,默认的参数在某些场景下可能不是最优的。对于大规模应用,推荐采用DC模式,动态分配通信资源。下表展示了可选的通信协议,其中shm和mm二选一,rc,ud,rc_x,ud_x,dc_x 可以选一个或多个。默认不设置时等同于UCX_TLS=all.

UCX_NET_DEVICES:用于指定IB设备端口。例如UCX_NET_DEVICES=mlx5_1:1,mlx5_2:1,mlx5_0:1,mlx5_3:1用于显式指定使用4个端口设备。

UCX_IB_ADDR_TYPE:用于指定GID寻址方式。受限于IB网络协议规范,LID最大65536,对于超大规模网络,必须采用GID寻址方式进行路由,需要指定为ib_global。

UCX_MAX_EAGER_LANES、

UCX_MAX_RNDV_LANES:用于通信通道数量设置,可指定通信资源lane的数量,当使用multiRail测试应该提供足够的lane数量,否则会影响带宽性能。

UCX_BCOPY_THRESH:BCOPY针对中等消息通信加速,该参数设置启用BCOPY的阈值。

UCX_ZCOPY_THRESH:确定使用非阻塞零拷贝操作(zcopy)进行数据传输的数据包大小。

UCX_RNDV_THRESH:用于设置启用RNDV协议的阈值。如果缓冲区高于阈值,则会触发Rendezvous协议,该参数对大数据通信带宽加速明显。

硬件标记匹配(TM)允许将点对点MPI消息的处理从主机卸载到卡上。它实现了MPI消息的零拷贝,即消息直接写入用户的缓冲区,而无需中间缓冲和拷贝。有三个TM卸载相关变量可能有助于调整启用卸载后没有任何改进的特定应用程序:

UCX_TM_THRESH:定义使用硬件标记匹配卸载的阈值。小于此值的消息将在软件中处理。

UCX_TM_FORCE_THRESH:强制标记匹配卸载模式的阈值。

综上常见的UCX相关设置为(仅供参考):

export UCX_NET_DEVICES=mlx5_0:1export UCX_TLS=self,sm,rcexport UCX_IB_ADDR_TYPE=ib_globalexport UCX_RNDV_THRESH=16384export UCX_ZCOPY_THRESH=16384export UCX_MAX_EAGER_LANES=4export UCX_MAX_RNDV_LANES=4

运行参数调优--HCOLL

MPI集合通信提供了一种灵活的方式来实现组通信操作,它们被广泛用于各种科学并行应用程序,并对整体应用程序性能产生重大影响。可以尝试使用HCOLL库(Hierarchical COLLectives)优化集合通信性能。

HCOLL利用硬件多播功能来加速集体操作。为了充分利用这一独特功能,首先应在集合通信消息流量流经的每个适配器卡/端口对上配置IPoIB。首先可以使用ibdev2netdev查看所有的IB端口,再使用ifconfig 命令查看是否已经为IB端口配置了IP地址。HCOLL版本目前支持“Allgather”、“Allgatherv”、“All reduce”、“AlltoAll”、“AlltoAllv”、“Barrier”和“Bcast”的阻塞和非阻塞版本。

I_MPI_COLL_EXTERNAL=hcoll启用hcoll,使用“hcoll_info -a”可以查看各个参数的含义和可设置值,本部分仅介绍部分参数。

HCOLL自带一组通信原语,称为bcolls

  • mlnx_pp(MXM)、ucx_p2p(ucx),basesmuma(SHM)和cc(跨通道);

  • HCOLL_BCOL用于定义进程组间的通信方法。

HCOLL自带一组定义子进程组的原语,称为sbgp

  • 包括Basesmsocket(Socket组)、Basesmuma(UMA组)、P2P(Network组);

  •  HCOLL_SBGP用于定义进程组。

例如,在执行AllReduce时设置以下环境变量,则在同一个socket下和同一个节点内会使用shared memory方法通信,在节点间会使用p2p方法通信。

HCOLL_SBGP=basesmsocket,basesmuma,p2p HCOLL_BCOL=basesmuma,basesmuma,ucx_p2p

运行参数调优--SHARP

HPC-X支持NVIDIA SHARP软件加速集合通信,SHARP通过将集合通信从CPU和GPU卸载到网络,消除了在端点之间多次发送数据的需要。

HCOLL_ENABLE_SHARP:设置为1可以启动该功能,设置为2时则为强制启用该功能。

HCOLL_BCOL_P2P_ALLREDUCE_SHARP_MAX:

allreduce算法通过SHARP运行的最大小消息大小,大小小于上述值的消息将使用SHARP流聚合方法,大于该值的则回退到HCOLL不基于SHARP的算法。

HCOLL_SHARP_NP:通信器中用于创建SHARP组和使用SHARP集合通信的节点数阈值,有助于有效使用SHARP资源。默认为2,可以通过调整该值略微改善性能。

部分参数因篇幅限制,不再详细列出,具体可参考intel相关手册。

引用:

  • https://www.intel.com/content/www/us/en/docs/dpcpp-cpp-compiler/developer-guide-reference/2023-0/intel-s-memory-allocator-library.html

  • https://www.intel.com/content/www/us/en/docs/mpi-library/developer-reference-linux/2021-8/environment-variables-for-process-pinning.html

  • https://www.intel.cn/content/www/cn/zh/developer/articles/technical/improve-performance-and-stability-with-intel-mpi-library-on-infiniband.html

  • https://www.intel.com/content/www/us/en/docs/mpi-library/developer-reference-linux/2021-8/i-mpi-adjust-family-environment-variables.html

  • https://www.intel.cn/content/www/cn/zh/developer/articles/technical/improve-performance-and-stability-with-intel-mpi-library-on-infiniband.html


     

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

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

相关文章

Java 4.2 - MySQL

MySQL 基础 关系型数据库 关系型数据库就是建立在关系模型上的数据库。关系模型描述了实体属性以及实体和实体之间的关系。 在关系型数据库中&#xff0c;我们的数据都被存放在了各种表中&#xff08;比如用户表&#xff09;&#xff0c;表中的每一行存放着一条数据。 常见…

QCheckBox 全部取消选中

当我有很多 QCheckBox 被选中后&#xff0c;如何批量全部取消勾选呐&#xff1f; 方法一&#xff1a;findChildren函数方法二&#xff1a;foreach循环效果展示&#xff1a; 方法一&#xff1a;findChildren函数 // 遍历所有 QCheckBox 并取消选中QList<QCheckBox*> check…

新冠期间,Raspberry Pi 400 在肯尼亚为2500名学生提供在线学习机会

学生需要设备进行远程学习&#xff0c;Raspberry Pi 400为他们提供了在线学习的机会。 当疫情来袭时&#xff0c;接受前线重要岗位培训的护理和助产专业学生不得不改用远程教学来完成部分学业&#xff0c;但许多人家里没有设备&#xff0c;无法访问在线资料。Wisenet 伸出援手&…

全面解读AI大模型:一文带你看懂发展脉络与未来走向!

引言 近年来&#xff0c;随着深度学习技术的迅猛发展&#xff0c;AI大模型已经成为人工智能领域的重要研究方向和热点话题。AI大模型&#xff0c;指的是拥有巨大参数规模和强大学习能力的神经网络模型&#xff0c;如BERT、GPT等&#xff0c;这些模型在自然语言处理、计算机视觉…

小区物业维修管理系统/小区居民报修系统

摘要 小区物业维修是物业公司的核心&#xff0c;是必不可少的一个部分。在物业公司的整个服务行业中&#xff0c;业主担负着最重要的角色。为满足如今日益复杂的管理需求&#xff0c;各类小区物业维修管理系统也在不断改进。本课题所设计的小区物业维修管理系统&#xff0c;使用…

SD-WAN企业组网解决方案能解决企业的哪些问题?

SD-WAN企业组网解决方案在现代企业网络建设中具有重要意义&#xff0c;能够有效解决企业面临的多项挑战&#xff0c;下文将对此进行详细描述&#xff1a; 首先&#xff0c;SD-WAN技术在节省企业网络建设和运维成本方面表现突出。相比传统网络架构依赖大量专线和昂贵设备的方式&…

ACM模式下算法题输入输出攻略【C++】

文章目录 [TOC] 1. 核心代码模式与ACM模式1.1 ACM模式介绍1.2 注意事项 2. C常用的输入输出方法2.1 输入2.1.1 cin注意事项2.1.2 getline()注意事项2.1.3 getchar()注意事项 2.2 输出 3. 案例3.1 一维数组输入3.1.1 固定长度的一维数组3.1.2 不固定长度的一维数组 3.2 二维数组…

Java学习_19_方法引用及异常

文章目录 前言一、方法引用方法引用实例引用静态方法引用成员方法引用构造方法使用类名引用成员方法引用数组的构造方法综合练习 二、异常异常是什么异常的作用处理方案默认异常捕获异常 异常对象的常用方法抛出异常 总结 前言 博客仅记录个人学习进度和一些查缺补漏。 学习内…

使用ckplayer控制视频播放

目录 1、加载视频流 1.1、html模块 1.2、js模块 2、其他功能 2.1、缩放窗口 2.2、旋转窗口 2.3、卸载播放器 2.4、监听播放时间进度 2.5、定位播放 3、初始化属性说明 4、使用功能一览 ckplayer是一款在网页上播放视频的软件&#xff0c;基于javascript和css&#xf…

黑神话:悟空!爆了很多猴头! 借力,借智,借势(深度好文)——早读(逆天打工人爬取热门微信文章解读)

黑神话&#xff1a;悟空 怎么这么多猴头呢&#xff1f; 引言Python 代码第一篇 洞见 借力&#xff0c;借智&#xff0c;借势&#xff08;深度好文&#xff09;第二篇 股市风云结尾 引言 天哪 我昨天忘记发了 原因有二 一是比较忙 大家明白那种 3000块工资干2W的活的感觉吧 一开…

PyTorch使用------模型的定义和保存方法(带你讯速掌握构建线性回归,保存模型的方法!!!)

&#x1f43b; PyTorch使用合集&#xff1a; PyTorch使用------张量的创建和数值计算-CSDN博客 PyTorch使用------张量的类型转换&#xff0c;拼接操作&#xff0c;索引操作&#xff0c;形状操作-CSDN博客 目录 &#x1f354; 模型定义方法 &#x1f498; 使用PyTorch构建线性…

RISC-V vector(1) --- vector的引入与register说明

Vector相较于SIMD的优势 这两种实现方案&#xff0c;都是为了实现数据级并行性&#xff08;存在大量的数据可供程序同时计算&#xff09;&#xff1b; SIMD&#xff08;Single Instruction Multiple Data&#xff09; SIMD是将数据宽度和操作类型&#xff0c;都放在了指令中&a…

网络初识部分

1.网络 单机时代-局域网时代-广域网时代-移动互联网时代 局域网时代&#xff1a;通过路由器把几个电脑连接起来。 广域网时代&#xff1a;把更多的局域网连接到一起&#xff0c;构成的网络更庞大&#xff0c;可能已经覆盖了一个城市/国家/全世界。 2.什么是路由器&#xff…

关于武汉芯景科技有限公司的多协议收发芯片XJ526(第二篇RS422模式)开发指南(兼容SP526)

一、设置芯片为RS422模式 SP526 包含高度集成的串行收发器。SP526 提供 RS-232 &#xff08;V.28&#xff09;、RS-423 &#xff08;V.10&#xff09;、RS-422 &#xff08;V.11&#xff09; 和 RS-485 的硬件接口模式。接口模式选择通过两个控制引脚D0、D1完成。 我们将D0接…

【简历】25届青岛某一本JAVA简历:中厂不要强调算法,面试官听不懂

注&#xff1a;为保证用户信息安全&#xff0c;姓名和学校等信息已经进行同层次变更&#xff0c;内容部分细节也进行了部分隐藏 简历说明 今天我们要看的是一位来自25届青岛某一本硕士同学的Java简历。 依旧是先判断自己要投什么层次的厂&#xff0c;也就是我们校招第一法则…

Netty04-优化与源码

四. 优化与源码 1. 优化 1.1 扩展序列化算法 序列化&#xff0c;反序列化主要用在消息正文的转换上 序列化时&#xff0c;需要将 Java 对象变为要传输的数据&#xff08;可以是 byte[]&#xff0c;或 json 等&#xff0c;最终都需要变成 byte[]&#xff09;反序列化时&…

SQL进阶技巧:如何按任意时段分析时间区间问题? | 区间重叠问题应用

目录 0 场景描述 1 数据准备 2 问题分析 方法1:分情况讨论,找出重叠区间 方法2:暴力美学法。按区间展开成日期明细表 3 小结 0 场景描述 现有用户还款计划表 user_repayment ,该表内的一条数据,表示用户在指定日期区间内 [date_start, date_end] ,每天还款 repay…

成为顶尖1%前端开发者的10项必备技能

从你可能已经熟悉的前端基础开始&#xff1b;然后进入关键技能&#xff0c;如使用浏览器开发工具和利用AI快速编码。包括99%的开发者忽视的宝贵通用技能。 从你可能已经熟悉的前端基础开始&#xff1b;然后进入关键技能&#xff0c;如使用浏览器开发工具和利用AI快速编码。 包…

【youcans论文精读】KAN 2.0:面向科学的KAN网络

欢迎关注『youcans论文精读』系列 本专栏内容和资源同步到 GitHub/youcans 【youcans论文精读】KAN 2.0&#xff1a;面向科学的KAN网络 1. KAN2.0 简介1.1 KAN 2.0 论文发布1.2 KAN2.0 的新特点&#xff1a;1.3 KAN 回顾 2. MultiKAN&#xff1a;用乘法增强 KAN 网络的表达能力…

足底筋膜炎专用药

足底筋膜炎专用药“古顺*敷堂筋膜*贴”通过其独特的药效和用法&#xff0c;能够针对足底筋膜炎进行有效治疗&#xff0c;缓解患者疼痛和不适感&#xff0c;促进炎症消退和肌肉恢复。长时间站立、行走或进行高强度的跑步、跳跃等活动&#xff0c;会使足底筋膜受到持续的牵拉和压…