自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(100)
  • 资源 (7)
  • 收藏
  • 关注

原创 CGSCC基本概念

CGSCC代表Call-Graph Strongly Connected Component,即调用图的强连通分量这是一个在编译器优化(特别是过程间优化)中非常重要的概念。

2025-06-05 10:42:14 748

原创 推荐系统总体架构

在深度学习中 Embedding 技术在召回层的应用。作为深度学习中非常核心的 Embedding 技术,将它应用在推荐系统的召回层中,做相关物品的快速召回,已经是业界非常主流的解决方案不同结构的深度学习模型在排序层的应用。排序层(精排层)是影响推荐效果的重中之重,也是深度学习模型擅长领域,深度学习模型的灵活性高,表达能力强的特点,这让她非常适合于大数据量下的精确排序。深度学习排序模型毫无疑问是业界和学界都在不断加大投入,快速迭代的部分增强学习在模型更新,工程模型一体化方向上的应用。

2025-06-05 10:41:44 257

原创 LLVM InstCombine

本文通过一个简单案例解析了LLVM中InstCombine优化流程。以"a+0"简化为例,展示了如何通过GDB调试InstCombinePass的运行过程,详细介绍了Pass在LLVM中的概念和作用。重点剖析了InstCombine的工作机制,包括其常量折叠、代数简化等功能实现,以及prepareICWorklistFromFunction函数如何初始化工作列表、处理指令和基本块。文章还提供了InstCombine在实际应用中的三种调用方式,并分享了相关参考资料,为理解LLVM优化器的工

2025-06-05 10:39:41 379

原创 右值和移动

通常可以放在等号左边的表达式, 左值例子。

2025-05-12 23:32:14 1042

原创 C++双重释放内存问题

在C++中,双重释放内存会导致未定义行为,通常引发程序崩溃这是因为同一块内存被多次释放会破坏内存管理器的内部数据结构双重释放是什么意思呢?

2025-05-09 11:29:32 522

原创 LLVM 中 的 pass 及其管理机制

在编译器开发时,可以混合使用两种方式,将各种pass组合为流水线,对IR做不同的处理和优化LLVM Pass 类及其子类的继承关系如下图所示。

2025-05-04 20:51:00 627

原创 LLVM Pass

/ 定义一个继承自FunctionPass的Pass类// 重写runOnFunction方法,实现具体的Pass逻辑// 在这里可以进行各种分析和优化操作// 注册Pass到LLVM Pass管理器中// 示例函数,使用MyPass进行优化分析// 创建Pass管理器// 添加MyPass到Pass管理器中// 运行Pass管理器PM.run(F);// 创建一个简单的函数// 在函数中添加一些指令// 运行优化分析return 0;

2025-05-04 20:48:29 384

原创 GBDT 基本概述

GBDT 是 Gradient Boosting Decision Tree 的缩写,属于集成学习方法中的 Boosting 族。它的核心思想是通过逐步构成多个决策树,每棵树都试图纠正前一棵树的残差,最终所有树的结果相加得到最终预测结果这里的关键点在于如何通过梯度下降来最小化损失函数,从而确定每棵树的参数。

2025-05-02 09:41:12 966

原创 仿射变换理论概述

并行性和局部性优化需要我们考虑一个循环的不同实例以及实例之间的关系。这个情况和数据流分析有着很大的不同。在数据流分析中,我们把所有实例的相关信息组合在一起考虑对于带有数组访问的循环的优化问题,我们使用三种类型的空间。每个空间可以看成是一维或多维栅格中的点集并并行化问题写成多维空间和这些空间之间的仿射映射使得我们可以使用标准的数学技术来解决并行化和局部优化问题比如,可以通过使用Fourier-Motzkin 消除算法消除相应的变量,找出被访问数据的区域。已经证明数据依赖性和整数线性规划问题等价。

2025-05-01 09:35:33 883

原创 梯度下降基本概述

梯度是一个向量,表示函数 J(θ) 在某点 θ 处增长最快的方向。数学表达式为负梯度方向 −∇J(θ) 是函数值下降最快的方向批量梯度下降(BGD): 使用全部数据计算梯度,计算慢但问题随机梯度下降(SGD): 每次随机选一个样本计算梯度,速度快但波动大小批量梯度下降(Mini-batch GD): 折中方案,常量批量大小 32 ~256学习率需合理设置(可通过网格搜索或自适应算法调整)特征标准化可加速收敛(如将输入数据缩放到均值为0,方差为1)监控损失函数曲线,判断是否收敛或过拟合。

2025-05-01 08:59:12 1029

原创 Word2vec Skip-Gram 模型

在Skip-Gram 模型中,存在两个权重矩阵。输入层到隐藏层的矩阵W和隐藏层到输出层的矩阵W’. 这个两个矩阵分别对应词向量的输入和输出表示。

2025-02-11 22:16:05 701

原创 数值型特征处理 - 归一化和分桶

将连续数值离散化为区间(桶),捕捉非线性关系或减少噪声影响,常用于树模型或逻辑回归。

2025-02-09 17:23:27 797

原创 拓扑 排序

拓扑排序是一种重要的图算法,适用于解决依赖关系问题。通过C++实现,可以清晰地理解其工作原理和实现细节。

2025-02-09 17:20:46 164

原创 Spark RDD

RDD是一种抽象,是Spark对于分布式数据集的抽象,它用于囊括所有内存中和磁盘中的分布式数据实体。

2024-10-26 22:28:18 1293

原创 Spark 基础操作

用于RDD创建工作。RDD创建只有两种方法,一种是来自于内存集合和外部存储系统,另一种是通过转换操作生成的RDD。

2024-10-26 22:27:45 1001

原创 定义类与类之间的交互关系

泛化(Generalization)概念可以简单理解为继承关系代码实现public class A { ... }public class B extends A { ... }实现(Realization)概念一般是指接口和实现类之间的关系代码实现public interface A {...}public class B implements A { ... }聚合(Aggregation)概念聚合是一种包含关系,A类对象包含B类对象,B类对象的生

2024-10-23 10:46:32 600

原创 改善代码质量的20条编程规范

代码嵌套层次过深往往是因为 if-else、switch-case、for 循环过度嵌套导致的个人建议,嵌套最好不超过两层,超过两层之后就要思考一下是否可以减少嵌套过深的嵌套本身理解起来就比较费劲嵌套过深很容易因为代码多次缩进,导致嵌套内部的语句超过一行的长度而折成两行,影响代码的整洁。

2024-10-23 10:44:03 825

原创 染色算法的简单概述

这句话描述的是一种用于确定寄存器分配的染色算法在这个上下文中,我们有一个图,图的节点代表变量,边代表变量之间的干扰(即两个变量不能共享同一个寄存器)算法的目标的是为了判断给定的k个寄存器是否足够给所有的变量分配如果一个图可以用k种颜色来染色(即每个节点可以用一个颜色表示,且相邻的节点颜色不同),那么添加一个边数少于k的节点,仍然可以用k种颜色来颜色。因为新节点的边数少于k,所以至少有一种颜色是没有被它的任何邻居使用的。

2024-09-22 11:03:23 530

原创 LLVM 中的Value、User、Use设计

首先,定义一个简单的LLVM IR 代码片段,这里创建一个简单的加法操作在这个例子中,%1是一个Value,它代表了加法操作的结果.i32 是它类型,表示这是一个32位的整数10 和 20 是操作数,它们也是Value。

2024-09-21 22:47:57 1490

原创 LLVM 寄存器分配

基本寄存器分配器是四种寄存器分配器中最简单的寄存器分配pass实现(<llvm_root/livm/lib/CodeGen/RegAllocBasic.cpp>)但麻雀虽小,五脏俱全,基本寄存器分配器中实现了根据溢出权重确实虚拟寄存器优先级、按优先级分配物理寄存器,以及物理寄存器不足时将虚拟寄存器溢出到内存等功能。因此,基本寄存器分配器非常适合作为自定义寄存器分配器实现参考LLVM3.0 之前的默认寄存器分配器是线性扫描分配器。

2024-08-11 10:48:23 778

原创 静态分析: 代码优化

Backward Analysis”或“反向分析”是一种分析技术,它从程序或代码的输出结果开始,逆向推导出程序的状态或者输入值这里的表达式“IN[s]=fs(OUT[s])”可以被解读为:给定一个状态s的输出OUT[s],通过某个函数fs来推导出该状态的输入IN[s]Reaching Definitions Analysis 是一种数据流分析技术,用于确定程序中某个变量定义对程序中其他点的可见性。

2024-07-27 10:40:11 885

原创 CPU 流水线相关情况

流水线中经常有一些被称为"相关"的情况发生,它使得指令序列中下一条无法按照设计的时钟周期执行,这些“相关”会降低流水线的性能流水线中的相关分为以下三种类型:结构相关、数据相关、控制相关。

2024-07-21 23:13:53 729

原创 长模式下的分页

长模式下的 4KB 分页下,由一个顶层目录、二级中间层目录和一层页表组成了 64 位地址翻译过程顶级页目录项指向页目录指针页,页目录指针项指向页目录页,页目录项指向页表页,页表项指向一个 4KB 大小的物理页各级页目录项中和页表项中依然存在各种属性位,这在图中已经说明其中的 XD 位,可以控制代码页面是否能够运行上图中没有了页表项,取而代之的是,页目录项中直接存放了 2MB 物理页基地址由于物理页始终 2MB 对齐,所以其地址的低 21 位为 0,用于存放页面属性位。

2024-07-21 15:25:47 415

原创 保护模式下的分页

页目录项、页表项都是 4 字节 32 位,1024 个项正好是 4KB(一个页),因此它们的地址始终是 4KB 对齐的低 12 位才可以另作它用,形成了页面的相关属性,如是否存在、是否可读可写、是用户页还是内核页、是否已写入、是否已访问等4MB 大小的页面下,页表项还是 4 字节 32 位,但只需要用高 10 位来保存物理页面的基地址就可以因为每个物理页面都是 4MB,所以低 22 位始终为 0。

2024-07-21 15:24:13 354

原创 MMU(内存管理单元)

它描述了虚拟地址到物理地址的转换关系,也可以说是虚拟页到物理页的映射关系,所以称为页表。

2024-07-21 15:22:53 541

原创 简单页表和多级页表

同样一个虚拟内存地址,偏移量的部分和上面简单页表一样不变,但是原先的页号部分,把它拆成四段,从高到低,分成4级到1级。以一个页的大小是4K字节(4KB)为例,我们需要20位的高位,12位的低位。因为虚拟内存地址分布的连续性,树的第一层节点的指针,很多就是空的,也就是不需要对应对应的子树。做地址转换的页表,只需要保留虚拟内存地址的页号和物理内存地址的页号之间的映射关系即可。找到最终最终的物理页号,就好像通过一个特定的访问路径,走到树最底层的叶子节点。所谓不需要子树,其实就是不需要对应的2级,3级的页表。

2024-07-21 15:19:11 1016

原创 CPU工作模式-长模式

保护模式下为了实现对中断进行权限检查,实现了中断门描述符,在中断门描述符中存放了对应的段选择子和其段内偏移,还有 DPL 权限如果权限检查通过,则用对应的段选择子和其段内偏移装载 CS:EIP 寄存器从实模式直接切换到长模式,也可以从保护模式切换长模式切换到长模式和切换保护模式的流程差不多,只是需要准备的段描述符有所区别,还有就是要注意同时开启保护模式和分页模式。

2024-07-21 15:17:17 450

原创 CPU工作模式- 保护模式

因为实模式下CPU不需要做权限检查,所以它可以直接中断向量表中的值装载CS:IP寄存器x86 CPU在第一次加电和每次reset后,都会自动进入实模式,想要进入保护模式,就需要程序员写代码实现从实模式切换到保护模式接下来,CPU 发现了 CRO 寄存器第 0 位的值是 1就会按 GDTR 的指示找到全局描述符表,然后根据索引值 8,把新的段描述符信息加载到 CS 影子寄存器,当然这里的前提是进行一系列合法的检查CPU 真正进入了保护模式,CPU 也有了 32 位的处理能力。

2024-07-21 15:16:20 1041

原创 CPU工作模式- 实模式

地址模式。

2024-07-21 15:14:42 447

原创 指令重排序

CPU由多个功能部件构成在这个结构中,一条指令执行时,要依次用到多个功能部件,分成多个阶段,虽然每条指令是顺序执行的,但每个部件的工作完成以后,就可以服务于下一条指令,从而达到并行的效果这种结构叫做。

2024-07-20 07:42:45 1545

原创 Verilog HDL 基本概念

(1) 等式运算符中的"" 与 "=" 的区别是: 对于"“运算,参与比较的两个操作数必须逐位相等,其结果才为1,如果某些值是不定态X或高阻态Z,那么得到的结果是不定值X;而对于”="运算,则要求对参与的操作数中为不定态X或高阻态Z的位与进行比较,两个操作数也必须完全一致,其结果才为1,否则结果为0针对上面的 a、b,"ab"的返回结果为X,而"a=b"的返回结果为1。

2024-07-18 07:19:38 1406

原创 对数的基本概念

特别地,我们称以10为底的对数叫做常用对数(common logarithm),并记为lg称以无理数e(e=2.71828…)为底的对数称为自然对数(natural logarithm),并记为ln零没有对数在实数范围内,负数无对数。[3] 在虚数范围内,负数是有对数的。

2024-07-14 22:08:03 809

原创 TCP中的拥塞控制

这两个结合起来就是AIMD算法,是使用最广泛的算法。拥塞避免算法不能够完全避免网络拥塞,通过控制拥塞窗口的大小只能使网络不易出现拥塞。

2024-07-14 22:04:40 868

原创 乘法器的基本操作

乘法因为只有“0”和“1”两种情况,所以可以做成输入输出都是 4 个开关,中间用 1 个开关,同时来控制这 8 个开关的方式,这就实现了二进制下的单位的乘法。这样,乘数和被乘数就像两列相向而驶的列车,仅仅需要简单的加法器、一个可以左移一位的电路和一个右移一位的电路,就能完成整个乘法。在展开之后呢,我们可以把原来需要较少的,但是有较多层前后计算依赖关系的门电路,展开成需要较多的,但是依赖关系更少的门电路。然后,把被乘数左移一位,把乘数右移一位,仍然用乘数去乘以被乘数,然后把结果加到刚才的结果上。

2024-07-14 16:45:10 821

原创 建立数据通路(三)

同样通过译码器,找出我们期望执行的指令,也就是在之前讲到过的opcode,以及后面对应的操作数或者寄存器地址,只是,这样的“译码器”,比如2-1选择器和3-8译码器,要复杂得多。这个自动计数器,可以拿来当PC寄存器,事实上,PC寄存器的这个PC,英文就是Program Counter,也就是。通过控制反相器的输入是0还是1,能够给决定对应的输出信号,是和地址A,还是地址B的输入信号一致。其实,译码器的本质,就是从输入的多个位的信号中,根据一定的开关和电路组合,选择出自己想要的信号。

2024-07-14 16:42:06 923

原创 建立数据通路 (二)

一个 D 型触发器,只能控制 1 个比特的读写,但是如果我们同时拿出多个 D 型触发器并列在一起,并且把用同一个 CLK 信号控制作为所有 D 型触发器的开关,这就变成了一个 N 位的 D 型触发器,也就可以同时控制 N 位的读写。实现这样一个电路,通过电的磁效应产生开关信号的方法是一样的,只不过,这里的磁性开关,打开的不再是后续的线路,而是当前线路。当我们把A前面的开关R合上的时候,A的输入变成了1和0,输出就变成了0,对应B的输入变成0,0,输出变成1。一个开关A,一开始是断开的,有手工控制。

2024-07-14 16:40:41 911

原创 寄存器分配

寄存器位于CPU 或 GPU内部的少量高速存储器,通常用于保存机器指令的操作数由于其价格昂贵,导致其数量有限,又由于存储速度快,使其不可或缺。因此,寄存器是计算机体系结构中的关键资源之一。在计算复杂表达式的过程中产生的中间结果都保存在寄存器中,更复杂的编译器会将经常使用的变量也保存在寄存器中,以避免反复存取如果是优化的编译器,还会将公共子表达式消除或者将循环不变量移动以后的重用值保存在寄存器中开发者在编写高级语言程序时会用到变量定义,如 int x, string y 等。

2024-07-13 21:26:13 1265

原创 调度pass的定制

作为调度pass实现类,MachineScheduler 和 PostMachineScheduler 的优点之一是允许开发者在LLVM 已有调度算法和策略基础上做不同的定制化。

2024-07-08 23:24:56 1006

原创 关联(Association) && 聚合(Aggregation) && 组合(Composition)

要符合聚合条件,整个对象及其各个部件必须具有以下关系该部件(成员)是对象(类)的一部分该部件 (成员) 一次可以属于多个对象(类)该部件 (成员)的存在不由对象(类)管理该部件(成员)不知道对象(类)的存在像组合一样,聚合仍然是部件与整体的关系,其中部件包含在整体中,并且是单向关系,但是与组合不同,部件一次可以属于一个以上的对象,而整个对象对部件的存在和生命周期不负责创建聚合时,聚合不负责创建部件,销毁聚合时,聚合不负责销毁部件例如,考虑一个人与其家庭住址之间的关系。

2024-07-07 08:59:37 1299

原创 建立数据通路(一)

之前说过,现在的Intel CPU 支持 2000 个以上的指令,意味着,控制器输出的控制信号,至少有2000种不同的组合。取出指令至少需要一个CPU周期,执行至少也需要CPU周期,复杂的指令则需要更多的CPU周期。控制器"翻译"出来的,就是不同的控制信号,这些控制信号,告诉ALU去做不同的计算。所以,我们说一个指令周期,包含多个CPU周期,而一个CPU周期包含多个时钟周期。一方面,所有CPU支持的指令,都会在控制器里面,被解析成不同的输出信号。操作的,指令的解码过程,也是由。里面完成,不需要用到运算器。

2024-07-05 23:12:21 987

C/C++ 一致性hash算法

一致性hash算法

2021-04-09

C/C++ 霍夫曼编码案例

霍夫曼编码

2021-04-09

bigFileTopN.zip

大文件关键字统计

2021-04-09

mergeSamilFile.zip

合并有序小文件

2021-04-09

C/C++ 求中位数的值

求中位数的值

2021-04-09

C/C++ 通过最大堆求topk

通过最大堆求topk

2021-04-09

C/C++ 高性能定时器应用

高性能定时器应用

2021-04-09

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除