- 博客(54)
- 收藏
- 关注
原创 GPU编程之Kernel优化的静态分析
本文探讨了如何结合软硬件优化算子性能,重点介绍了Roofline模型的理论框架和算法选型方法。首先通过Roofline模型判断任务是计算受限(Compute-Bound)还是带宽受限(Memory-Bound),据此确定优化方向。然后根据算子类型(密集计算、访存密集、规约归一化、IO感知)选择最佳算法策略,如使用Winograd卷积或FlashAttention。文章提出了算法增益系数量化评估算法优化效果,并以Attention算子为例展示了不同实现方案的性能差异。这种系统化的优化方法比盲目试错更高效,能帮
2026-02-09 10:55:33
619
原创 GPU编程之Elementwise算子
Elementwise算子又称为逐元素算子,指的是对输入张量的每个元素独立应用相同运算的操作,包括基本的算术运算、激活函数、数学函数等。其作为GPU编程中最基础、最频繁使用的一类操作,其性能优化直接影响到整个计算系统的效率。与需要线程间通信的归约操作、矩阵乘法不同,Elementwise算子的最大特点是**完全的数据并行性**——每个元素的处理都是独立的。
2026-02-04 18:22:43
879
原创 稀疏矩阵—CSR格式学习
CSR(Compressed Sparse Row)是一种高效存储稀疏矩阵的格式,通过三个数组实现:values存储非零元素,col_indices记录列索引,row_pointer标记每行起始位置。该格式节省空间且便于行操作,适合并行计算。访问元素时需先定位行范围再搜索列索引。示例代码展示了如何将稠密矩阵转换为CSR格式,并实现元素查找功能。CSR格式特别适合非零元素分布不均匀的稀疏矩阵,能显著减少存储空间和计算开销。
2026-01-14 18:03:34
856
原创 从数独游戏里看小范围重复判断场景问题
本文探讨了验证数独有效性的两种方法。第一种方法使用哈希表(数组模拟)检查数字是否在1-9范围内且不重复,时间复杂度为O(n^2)。第二种方法采用位运算优化,通过二进制位标记数字存在性,性能提升约2.2倍(实测266ms vs 591ms)。文章详细说明了位运算的实现原理:利用1<<num定位、|操作合并状态、&操作检测重复。最后扩展了位运算的适用场景,包括状态压缩、权限校验等,并总结了六种位运算的特性与典型应用场景,如权限管理、数据加密和性能优化等。位运算特别适合处理小范围整数的快速状态
2025-12-30 19:25:26
909
原创 GPU编程之warp级编程
Warp是GPU中线程调度的基本单元,32个线程组成一个Warp,采用SIMT模式同步执行相同指令但处理不同数据。Warp的特性包括固定大小、隐式同步和分支分化问题。内存访问优化方面,共享内存需避免Bank Conflict,全局内存需满足合并访问条件以提高带宽利用率。以规约求和为例,相比串行求和,Warp级归约通过__shfl_down_sync指令实现高效数据交换,性能显著提升。优化策略包括合理组织线程索引、使用向量类型和数据结构对齐等。
2025-12-07 20:36:39
1308
原创 GPU编程之共享内存篇(Shared Memory)
GPU中的Shared Memory是一种高效的块级内存,用于加速线程块内的数据共享和协作。相比全局内存,Shared Memory具有更低的访问延迟(数十周期 vs 数百周期),但容量有限(通常64KB)。其核心用途包括:1)数据重用(如矩阵乘法中复用子矩阵);2)块内线程通信(如归约运算);3)优化内存访问模式(如矩阵转置)。使用时需注意避免Bank Conflict,并通过__shared__声明静态内存或extern动态分配。优化技巧包括合理设置Tile大小、多类型内存偏移等,可显著提升计算密集型任
2025-12-05 10:07:29
1030
原创 GPU编程之核函数的配置
本文系统探讨了CUDA核函数的线程配置与优化策略。首先解析了核函数的基本概念与三级线程组织模型(线程→线程块→网格),详细说明线程ID计算方法和数据映射关系。其次,通过固定规模数据处理和多维图像处理两个典型案例,对比不同线程配置(如4×8、8×4、4×4)的特点与适用场景。最后提出硬件资源匹配、数据局部性优化和负载均衡三大配置原则,强调需结合具体算法需求与GPU架构特性进行参数调优,以充分发挥GPU并行计算潜力。文章为CUDA编程中的线程组织提供了实用指导。
2025-11-21 09:46:25
866
原创 GPU编程之线程ID的分配
GPU并行计算采用“网格-块-线程”三级模型,核心优化原则包括:根据硬件特性(如SM/CU数量)配置线程块大小;数据结构匹配(如矩阵用16×16线程块);避免线程束分化。案例显示合理划分可显著提升卷积和LLaMA推理性能。未来线程管理需持续平衡硬件架构、数据特征与算法需求。
2025-11-20 10:17:06
1055
原创 四十年坚守,AI时代再续传奇的C++
从大一初学C++的"Hello World"到AI时代底层支柱,作者回顾了8年编程历程。经历了初期的指针困惑、Java/Python的诱惑后,在研究生阶段重新发现C++在高性能计算和AI底层开发中的不可替代性。文章展示了现代C++在AI推理、并发编程和CUDA协同中的优雅应用,揭示了历经40年演进的C++依然是支撑数字世界的核心力量。这段技术成长历程印证了基础技术的重要价值:真正优秀的技术不在于追逐潮流,而在于解决本质问题。
2025-11-19 10:19:22
769
原创 GPU编程之网格和线程块
摘要:本文介绍了CUDA编程中线程组织的层次结构。一个kernel启动的所有线程构成一个grid网格,网格划分为多个线程块block,每个块包含多个线程。通过dim3类型定义grid和block的维度(1D/2D/3D),使用执行配置<<<grid,block>>>指定线程结构。每个线程通过blockIdx和threadIdx唯一标识位置,并给出了不同维度组合下计算全局线程索引的公式:1D网格和块使用id=blockIdx.x*blockDim.x+threadIdx.x
2025-11-18 17:46:34
1286
原创 了解GPU的秘密
GPU从图形处理器发展为通用算力核心,凭借其高度并行架构成为AI时代的算力支柱。与CPU"少而精"的通用计算不同,GPU以数千个流处理器(如NVIDIA的CUDA核心)实现大规模并行计算,完美适配图形渲染、AI训练等重复密集型任务。其性能取决于流处理器数量和显存(带宽与容量),应用场景已从游戏影音扩展到科研设计、AI模型训练与推理。随着算力需求爆发,GPU的并行计算优势将持续推动技术革新。
2025-11-18 17:36:47
1775
原创 NumPy性能密码:Python循环优化方法
从"元素思维"到"数组思维":放弃逐个处理元素的习惯,用批量运算的视角审视问题理解底层原理而非死记技巧:掌握连续内存和向量化的核心逻辑,才能应对不同场景的优化需求正确性优先于速度:优化前先确保原始逻辑正确,优化后通过基准测试验证结果一致性正如在案例中看到的,从8层嵌套循环到265倍加速,并非依赖渐进式的小优化,而是找到核心问题(循环无法利用NumPy优势)后,用向量化运算一击即中。掌握这种思维,才能真正让NumPy成为你的性能利器。
2025-11-10 17:32:57
687
原创 WSL-Ubuntu忘记root密码,修改root密码
摘要:本文介绍了在Windows系统中通过WSL重置Ubuntu系统密码的方法。首先以管理员身份打开PowerShell,使用wslconfig /l查看WSL-Ubuntu版本信息。然后通过wsl.exe --user root命令登录root账户(可指定具体版本),使用passwd root重置root密码。若要重置其他用户密码,只需在最后一步将命令改为passwd username即可。整个过程简单明了,适用于忘记WSL-Ubuntu密码的情况。
2025-11-04 10:00:52
906
原创 Python实现pdf文件转word文件
日常生活中,当遇到需要将某个PDF文件转换为Word格式文件时,一般是通过一些在线格式转换的网站,或者软件来完成,但我们也可以使用python来完成这个需求(当然,这种方法仅能够满足大部分的格式)。
2023-12-01 10:47:52
1486
2
原创 己知一棵有 2011 个结点的树,其叶结点个数为 116,该树对应的二叉树无右孩子的结点个数是
树转二叉树的规则:每个结点左指针指向它的第一个孩子,右指针指向它在树中相邻的右兄弟,即“左孩子右兄弟“。拓展:树中一个叶子节点在转化为二叉树的时候,如果它有右兄弟,那么它右指针会指向其兄弟节点,此时该叶子节点不再是叶子节点;如果他没有兄弟节点,转化后仍然是叶子节点。(即不论哪种情况,该节点都没有左孩子。树转化成二叉树的画法:①在兄弟结点之间加一连线;②对每个结点,只保留它与第一个孩子的连线,而抹掉与其他孩子的连线;③以树根为轴心,顺时针旋转45°。
2023-10-24 19:31:33
871
原创 设x为整数,[x]补=1,x1x2x3x4x5,若要x<-16,x1~x5应满足的条件是()
设x为整数,[x]补=1,x1x2x3x4x5,若要x
2023-10-09 21:09:33
1267
原创 若[x]补 =1,x1x2x3x4x5x6,其中x取0或1,若要x>-32,应当满足
若x补1x1x2x3x4x5x6其中x取0或1,若要x−32,应当满足()Ax1为0,其他各位任意Bx1为1,其他各位任意Cx1为1x2……x6至少有一位为1Ax1为0x2……x6至少有一位为1[x补−32补y补两个补码相加得到的x补,而x1的位置,显然是1,且x2。
2023-04-27 17:42:31
1548
原创 线性表元素的区间删除(一步步带你思考解答)
给定一个顺序存储的线性表,请设计一个函数删除所有值大于min而且小于max的元素。删除后表中剩余元素保持顺序存储,并且相对位置不能改变。函数接口定义:List Delete( List L, ElementType minD, ElementType maxD );其中List结构定义如下:typedef int Position;typedef struct LNode *List;struct LNode { ElementType Data[MAXSIZE]; Posit
2021-05-14 23:17:25
2109
1
原创 判断一条链表中有无环路
两种链表一、普通单链表二、有环链表问题:判断一条链表中是否存在环。思路一:哈希存储,通过set集合存储遍历过的结点,遍历过程中检查set,若set中已存在某节点,则证明有环,返回true,若遍历正常结束,最终返回false,无环。(该方法易实现,此处略写。)思路二:双指针、快慢指针,设置一个fast指针和slow指针,slow每次移动一次(slow = slow.next),fast 每次移动两次(fast = fast.next.next)。若存在环,fast指针先进入环内循环,sl
2021-05-14 09:29:44
338
4
原创 寻找单链表的中间项
问题:寻找一条单链表中的中间项的值。链表结构体typedef struct Node{ int value; struct Node* next;}*Link;思路:使用快慢指针,设置两个指针(slow,fast)分别指向链表第一项,slow每次移动一次(slow = slow.next) ,fast 每次移动两次(fast = fast.next.next),当fast遍历完整条链表后,slow的位置即是中间项的位置。动画模拟:代码实现:int findMid(
2021-04-24 15:24:53
326
原创 自测-3 数组元素循环右移问题(一遍懂,两种方法)
一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A0A1⋯A**N−1)变换为(A**N−M⋯A**N−1A0A1⋯A**N−M−1)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?输入格式:每个输入包含一个测试用例,第1行输入N(1≤N≤100)和M(≥0);第2行输入N个整数,之间用空格分隔。输出格式:在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不
2021-02-05 22:24:48
1882
原创 巧记LinkedList常用方法。
LinkedList类的方法比较多,总结一些常用的方法以及作为特定容器下的方法,方便记忆使用。文章目录一、作为链表基本用法二、作为堆栈基本用法三、作为队列基本用法一、作为链表基本用法增方法名返回值方法参数方法简介addboolean(E e)向尾部添加指定的元素。addvoid(int index, E element)在指定下标插入指定元素。删方法名返回值方法参数方法简介removeE(int index).
2021-02-04 22:00:37
415
原创 头插法和尾插法总结(动图版)
代码使用结构体:typedef struct Node{ int value; struct Node* next;}*Link;头插法:利用头指针控制链表节点的增加。核心:newNode->next = head->next;head->next = newNode;//头插法创建链表Link headCreateLink(int n){ //头指针初始化部分 Link head,newNode; head = (Link)malloc(sizeo
2021-02-03 22:44:58
33085
15
原创 7-52、两个有序链表序列的交集
已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的交集新链表S3。输入格式:输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。输出格式:在一行中输出两个输入序列的交集序列,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL。输入样例:1 2 5 -12 4 5 8 10 -1输出样例:2 5一开始用Java写了两遍,都无法全部通过,最后一个样例不是运行超时就是内存超限,有用Java通过的小伙伴
2021-02-02 20:49:06
601
1
原创 6-7 在一个数组中实现两个堆栈 (20分)
本题要求在一个数组中实现两个堆栈。函数接口定义:Stack CreateStack( int MaxSize );bool Push( Stack S, ElementType X, int Tag );ElementType Pop( Stack S, int Tag );其中Tag是堆栈编号,取1或2;MaxSize堆栈数组的规模;Stack结构定义如下:typedef int Position;struct SNode { ElementType *Data; Posi
2021-02-01 21:05:36
217
1
原创 (两种方法)已知长度为n的线性表A采用顺序存储结构,请写一时间复杂度为O(n)、空间复杂度为O(1)的算法,该算法删除线性表中所有值为item的数据元素
为了方便描述过程,假定一个线性表结构体ArrayListtypedef struct ArrayList{ int data[N]; int index;//初始值为-1,代表里面没有元素,使用时代表下标。}*List;第一种方法:顺序双指针法指针i控制向后遍历,指针j记录需要交换的位置。、1、进入循环,当遇到item元素时,不做任何处理,否则将指针i指向的值赋予指针j的位置,且指针j右移2、循环终止,最终将线性表的index等于j-1的位置。(最后一步的index位置,看i
2021-01-31 23:15:59
13668
6
原创 数组的复制(Java技巧篇,四种方法详解)
使用java.lang.System类中的arraycopy方法优点:该方法可复制全部内容,也可复制一部分成为子数组,且目标数组与源数组没有关系,目标数组可以比源数组大,比较灵活。缺点:返回值为void,所以需要手动创建目标数组。/** *参数含义 * @param src 源数组(需要复制的数组) * @param srcPos 源数组中的起始下标。!注意是下标! * @param dest 目标..
2021-01-30 22:21:55
533
1
原创 PTA 6-1 单链表逆转 (20分) 三种解法
PTA 6-1 单链表逆转 (20分) 三种解法本题要求实现一个函数,将给定的单链表逆转。函数接口定义:List Reverse( List L );其中List结构定义如下:typedef struct Node *PtrToNode;struct Node { ElementType Data; /* 存储结点数据 */ PtrToNode Next; /* 指向下一个结点的指针 */};typedef PtrToNode List; /* 定义单链表类型 */
2021-01-08 22:06:29
1589
1
原创 微信小程序——页面生命周期函数的总结
微信小程序——页面生命周期函数的总结onLoad页面加载 /** * 生命周期函数--监听页面加载 一个页面在卸载(销毁)前只会调用一次。 接收页面参数的来源有wx.navigateTo,wx.redirectTo和<navigator>中的query值 */onLoad: function (options) { },onShow页面显示 /** * 生命周期函数--监听页面显示 页面每次被打开都会执行该方法。
2020-11-18 22:25:03
5506
1
原创 微信小程序css卡片样式(带阴影效果)
微信小程序css卡片样式(带阴影)效果图wxml代码<view class="card"> </view> css样式.card{ width: 90%; margin-left: 5%; height: 390rpx; background: rgb(226, 208, 208); border-radius: 10rpx; box-shadow: 5px 5px 5px #cdcfcf; }css样式表注释/*卡片的宽度*/
2020-11-13 19:26:10
12412
2
原创 微信小程序学习——增加选项、删除选项
微信小程序 单击按钮后多添加一个输入框首先 WXML中要设置循环,实现动态的添加和删除<view> <view class="lines"> <button class="btn1" bindtap="add">添加</button> <button class="btn1" bindtap="delete">删除</button> </view> <view wx:for="{{re
2020-11-01 08:56:08
1932
原创 微信小程序 WeUI 之拓展组件tabs的引用。
微信小程序 WeUI 使用拓展组件tabs方法注意:不能使用 引入useExtendedLib 扩展库 的方式,而是用npm构建的方式。第一步:在项目根目录下打开终端。(我的是miniprogram)第二步:终端里输入:npm i @miniprogram-component-plus/tabs --save第三步:点击微信开发者工具的工具中,找到构建npm完成后在其目录下会生成一个miniprogram_npm\@miniprogram-component-plus\tabs目
2020-08-28 21:09:03
5352
原创 微信小程序简单使用拓展组件库方法
微信小程序使用拓展组件库方式:通过 useExtendedLib 扩展库 的方式引入方法:在全局app.json中添加"useExtendedLib": { "kbone": true, "weui": true }好处:在使用时可省略 import 步骤(相对于npm构建来说)使用: 先在所要引用的页面的json文件中添加对应组件名称(不需要在wxss中导入)例:{ "usingComponents": { "mp-cells": "weui-minipro
2020-08-25 20:16:22
2339
原创 leetcode:从上到下打印二叉树 II(层次遍历DFS与BFS版)
剑指 Offer 32 - II. 从上到下打印二叉树 II从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。例如:给定二叉树: [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7返回其层次遍历结果:[ [3], [9,20], [15,7]]看题就知道是层序遍历,模板题,BFS进行遍历即可,注意点是root为null时不是返回null,而是返回[],所以需要先new出来一个
2020-08-06 10:11:35
250
原创 leetcode:对称二叉树
101. 对称二叉树给定一个二叉树,检查它是否是镜像对称的。例如,二叉树 [1,2,2,3,4,4,3] 是对称的。 1 / \ 2 2 / \ / \3 4 4 3但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的: 1 / \ 2 2 \ \ 3 3看题第一想法就是一层一层的来,判断每一层是不是对称的,想着用队列BFS做,空的子树按照null来比较,下一层进队的时候按照front.left与re
2020-08-05 09:50:05
246
原创 leetcode:翻转二叉树
226. 翻转二叉树翻转一棵二叉树。示例:输入: 4 / \ 2 7 / \ / \1 3 6 9输出: 4 / \ 7 2 / \ / \9 6 3 1我觉得这道题叫做镜像二叉树应该也可以吧。思路:首先想到的就是相当于一个镜像,而且是左右子树进行交换位置。代码就根据简单的树的遍历,借助于临时变量作为左右子树交换的媒介,然后递归。先写树的遍历框架:public TreeNode invertT
2020-08-04 21:06:22
169
原创 leetcode:删除排序数组中的重复项
删除排序数组中的重复项(力扣26)给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。示例 1:给定数组 nums = [1,1,2],函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。你不需要考虑数组中超出新长度后面的元素。示例 2:给定 nums = [0,0,1,1,1,2,2,3,3,4],函数应该返回
2020-08-03 21:44:24
523
原创 Java学习之反射机制
Java高级之反射Java反射机制是在程序的运行状态中,可以获取类或者对象的信息,包括对象所属的类,类的成员变量和方法,对象的属性和方法。基本使用涉及到的类:Class类、Constructor类(构造方法)、Method类(普通方法)、Field类(属性字段)。一、获取类对象。Java是一门面向对象的语言,所以通常使用的类也是对象,是特殊的类Class 的对象。Class 没有公共构造方法,Class 类的实例表示正在运行的 Java 应用程序中的类和接口。所有具有相同元素类型和维数的数组都
2020-07-24 16:30:00
156
2
原创 单例模式设计实现(四种方法)
Java单例设计模式一个类有且只有一个实例,保证在内存中只存在一个实例化的对象,避免对同一资源的多重占用。作用:创建一个类对象时,保证全局对外只提供一个实例对象,提供一种访问该类的唯一对象方式,直接访问不需要进行实例化。能够避免全局使用类被频繁创建销毁时的资源浪费。缺点:无接口,不能被继承。(static修饰所致)单例设计模式要素:一个私有的构造器一个私有的该类类型的变量必须有一个共有的返回类型为该类类型的方法,用来返回这个唯一的变量常用的四种单例设计模式(多使用饿汉式。)(使用p
2020-07-08 17:09:51
384
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅