自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(101)
  • 问答 (1)
  • 收藏
  • 关注

原创 指令调度(Instruction Scheduling)

指令调度是为了提高,对于超长指令字(VLIW, Very Long Instruction Word)和多发射系统,ILP是可以有效提高硬件利用率。

2023-07-29 09:24:54 1633

原创 寄存器分配:图着色算法

本文介绍了比较经典的图着色的寄存器分配算法,此外目前使用比较广的还有线性扫描算法、整数线性规划算法等。在编译器的中间表示中,一般会设定虚拟寄存器有无限多个(方便优化),而真实的物理寄存器是有限的,因而编译器后端在将中间表示翻译成目标指令集的时候会进行寄存器分配,也就是将无限的虚拟寄存器映射到有限的物理寄存器上。图着色算法首先要进行活跃分析,得到冲突图,然后通过对冲突图进行着色来解决寄存器分配问题。寄存器分配的问题就可以转换为冲突图图着色问题。图着色是给图的每个顶点进行着色,并且相连的顶点需要着不同的颜色。

2023-07-29 09:05:39 2529

原创 强连通分量(SCC, Strongly Connected Components)

强连通分量及其Tarjan算法

2023-05-27 08:10:11 7080 1

原创 二叉堆(Binary Heap)

二叉堆其实就是一个完全二叉树(完全二叉树的介绍见二叉树(Binary Tree):先序遍历、中序遍历、后序遍历和层次遍历),只不过用数组存储形式。这里特意保留arr[0]不用,这样可以方便地计算父亲和儿子节点的index。因此,arr[1]是二叉树的根节点。最大堆:每个节点的值都大于等于它的两个子节点。最小堆:每个节点的值都小于等于它的两个子节点。显然,最大堆最大的元素就是其堆顶arr[1],最小堆最小的元素就是其堆顶arr[1]。

2023-04-28 23:03:20 1359 1

原创 XLA IR:HLO、LHLO、MHLO和LMHLO

(M)HLO的op是tensor类型,是不可变的 (immutable)、并且不具有 side effect,tensor的数据流分析(例如ssa def-use chain )和转换会比较容易。而L(M)HLO是经过buffer assign的,buffer 是可变的 (mutable)和有别名的 (alias),buffer上分析和转换需要比较复杂的依赖分析 (dependency analysis) 和别名分析 (alias analysis)。

2023-04-22 19:43:09 2337

原创 AI编译器前端:动态图转静态图的问题

python因其易用性和灵活性,被广泛应用于深度学习框架和AI编译器前端。像现在火爆的pytorch框架推崇python first哲学,pytorch这种命令式的执行方式(eager模式)非常方便研发和调试。但是eager模式不方便生产部署,也不能发挥硬件的极致性能。pytorch 2.0正式引入图编译器作为后端,可能也是想做到动静结合,收敛之前的多条编译器路线(torch.jit.script、torch.jit.trace、LazyTensor)到TorchDynamo方案。python作为动态语言

2023-03-05 08:37:32 1668

原创 死代码删除(DCE,Dead Code Elimination)和激进的死代码删除(ADCE,Aggressive DCE)

DCE和ADCE算法

2023-03-04 11:40:50 2421

原创 gdb调试小技巧:设置数组、容器和字符串元素的打印个数

gdb调试小技巧:设置数组、容器和字符串元素的打印个数在使用gdb调试的时候,遇到打印数组(array)、容器(vector)和字符串(string)等遇到元素打印不全的问题:gdb默认只会打印200个元素,我们当然可以通过下面的方法继续打印剩余元素:p array[index]@num但更直接的方法是修改默认的打印元素个数:如果我们想修改打印更多或者全部元素个数,可以通过 “set print elements number-of-elements”、"set print elements

2023-02-18 08:47:47 1764

原创 记一个奇怪的gcc编译优化:-ftree-vrp

记一个奇怪的gcc编译优化:-ftree-vrp

2023-01-14 09:53:43 3229 2

原创 内存问题检查工具——Address Sanitizer(ASAN)

ASAN工具使用介绍

2022-12-31 08:45:57 4108 1

原创 仿射变换(affine transformation)

关键词:线性变换、仿射变换、多面体编译。

2022-12-10 09:43:19 3049

原创 中间代码生成(Intermediate Code Generation)

关键词:上下文无关文法、语法分析、中间表示、三地址代码、语法制导翻译、控制流图。

2022-12-03 11:40:23 5203

原创 语法制导翻译(Syntax-Directed Translation)

关键词:语法制导翻译、语法制导定义、语法制导方案、SDD、SDT、语法分析、上下文无关文法

2022-11-26 12:38:15 7590 1

原创 自底向上语法分析(bottom-up parsing)

自底向上语法分析是从分析树的底部(叶子节点)向顶部根节点方向构造分析树,也即是将输入串归约为文法开始符号的过程。自顶向下的语法分析是采用最左推导方式,而自底向上的语法分析是采用最左归约方式,其实就是反向构造最右推导。自顶向上语法分析的通用框架是:移入-规约分析(Shift-Reduce Parsing)。下面通过一个例子来介绍移入-规约分析的算法思想。对输入串的一次从左到右扫描过程中,将零个或多个输入符号移入到栈的顶端,直到它可以对栈顶的一个文法符号串 β 进行归约为止。

2022-11-05 08:33:30 3628 1

原创 自顶向下语法分析(top-down parsing)

介绍自顶向下语法分析,包括有回溯的算法、无回溯算法、FIRST 集合、FOLLOW 集合、消除左递归、提取左公因子、LL(1)文法、下推自动机

2022-10-29 11:13:51 5862

原创 上下文无关文法(CFG)

关键词:上下文无关文法、CFG、BNF、语法分析树、语法分析。

2022-10-22 12:40:33 18124 4

原创 正则表达式(RE)、有限自动机(FA)和词法分析(LA)

关键词:正则表达式、RE、有限自动机、DFA、NFA、词法分析器、Thompson算法、子集构造算法、Hopcroft算法

2022-10-22 10:34:29 5836

原创 Effective Modern C++ 完全解读笔记汇总

Effective Modern C++ 系列学习和解读笔记汇总。

2022-10-04 19:27:07 7035 1

原创 Item 42: Consider emplacement instead of insertion.

介绍容器empalce系列接口的优势和使用场景。

2022-10-01 17:56:58 2400

原创 Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied.

介绍C++值传递的价值、应用场景和优势。

2022-10-01 16:21:01 1932

原创 C++ 按值传递的切割问题(Slicing Problem)

C++ 值传递时的切割问题

2022-10-01 16:01:06 2173

原创 Item 40: Use std::atomic for concurrency, volatile for special memory.

Item 40: Use std::atomic for concurrency, volatile for special memory.本 Item 探讨一下 atomic 类型和 volatile 关键字在并发程序中的区别和应用。C++11 提供了 std::atomic 类模版,可以保证操作的原子性,确保其他线程看到的肯定是操作后的结果。类似对操作加锁,而其内部使用特殊指令实现,因而开销较小。考虑下面的应用场景:std::atomic<int> ai(0); // initial

2022-09-24 09:03:27 1781

原创 Item 39: Consider void futures for one-shot event communication.

对于两个异步任务,经常需要一个任务(检测线程)告诉另一个任务(反应线程)特定的事件已经发生了,反应线程可以继续执行了。这个事件可能是某个数据结构被初始化了,某一阶段计算完成了,或者一个传感器数据已经采集好了。需要一种机制来完成两个任务线程间的通信,有哪些比较好的方法呢?

2022-09-17 22:46:01 1950

原创 共享库的加载时重定位和位置无关代码(Load-time Relocation and Position Independent Code of Shared Libraries)

介绍加载时重定位和位置无关代码。关键词为 PIC、PLT、GOT 和 延迟绑定。

2022-09-17 09:33:41 4544 1

原创 cuda-gdb 支持内置变量的实现机制

cuda-gdb 处理内置变量的方案。

2022-09-03 09:54:57 3195

原创 C++ 多线程编程系列一:线程管理(std::thread 对象、join、detach、传参、不可拷贝性、所有权转移)

每个 C++ 程序至少有一个线程,并且是由 C++ 运行时启动的,这个线程的线程函数就是 函数。你可以在这个线程中再启动其他线程。 的构造函数申明如下:线程的启动C++ 标准库提供了 以支持多线程编程。这里先介绍通过初始化构造函数创建 对象的方式启动线程。例如: 创建了一个 对象 ,并指定了线程函数 ,随机即启动了线程。 会阻塞到线程函数执行完成。线程任务可以是任意的可调用类型(callable type)。可调用类型包括:例如,可调用类型为仿函数时:但是,这个时候需要注意下面启动线程的方式

2022-08-27 09:14:19 3153

原创 C++‘s most vexing parse

这段代码很简单,在主线程(main函数)中起动一个子线程,并等待子线程执行完成。,参数为一个函数指针(返回值类型为 task,无函数名,参数为空)。第二个申明中行参省去指针类型也是合法的,第三个申明中行参直接省去了函数名也是合法的。第二个申明,对行参加上圆括号,编译器会认为是冗余的并忽略。第三个省略了行参名。再看本文开头给出的例子,就不难理解编译报错的原因了。对象并启动该线程执行,而是申明了一个函数,该函数的返回值类型为。根本就不是一个类类型的对象,而是一个函数,这里的。至此,本文结束,希望对你有所帮助。

2022-08-20 09:27:55 3331

原创 Item 38: Be aware of varying thread handle destructor behavior.

那么这个结果就需要被拷贝多次,不是所有结果的类型都是可以拷贝的。其实 callee 的结果是被存储在独立于 caller 和 callee 之外的特殊位置,被成为共享状态(shared state)的位置。直观地观察,被调用者(callee)和调用者(caller)之间有一个通信通道(channel),callee 异步执行完成后,将结果写入(通常通过。再者,callee 的结果也不能存储在 caller 的。方法之前,callee 可能已经结束了,callee 的局部变量。一个 joinable 的。

2022-08-20 08:40:45 1737

原创 编译时编程(Compile-Time Programming)

C++ 有很多方式可以实现编译时计算,而模板为编译时计算提供了更多的可能。constexpr本文将介绍这些特性。

2022-08-13 10:04:05 1903

原创 Item 37: Make std::threads unjoinable on all paths.

每个 只会处于两种状态状态之一:其一为 ,其二为 。一个 的 对应于一个正在或可能在运行的底层线程。例如,一个对应于处于阻塞或者等待调度的底层线程的 是 。对应于底层线程的 已经执行完成也可以被认为是 。而 的线程包括: 的 状态之所以重要的原因之一是:一个 状态的 对象的析构函数的调用会导致正在运行程序停止运行。例如,我们有一个 函数,它接收一个过滤函数 和一个最大值 作为参数。 检查并确定所有条件满足时,对 0 到 执行 。对于这样的场景,一般会选择基于任务的方式来实现,

2022-08-06 15:33:59 2101 1

原创 Item 36: Specify std::launch::async if asynchronicity is essential.

中讨论的标准库的线程管理模块承担了线程的创建和释放的职责,可以有效避免超额订阅、保证负载均衡。要访问本地线程存储(TLS,ThreadLocalStorage)时,无法预测访问的是哪个线程的本地存储。执行一个函数或可调用对象时,你通常期望这个函数是异步执行。综上,如果你的使用场景不是以下几种,则需要考虑是否需要替换。,以上代码就会有问题。,以上代码没有问题。但是,如果执行策略为。是根据执行策略决定是否会异步执行。可能是同步执行也可能是异步执行。是并发执行,也即执行策略为。有两种执行策略,定义在。...

2022-07-30 19:41:32 2089

原创 值传递还是引用传递(By Value or By Reference)

对于模板实参,选择值传递还是引用传递时一个复杂的问题。虽然通常情况下引用传递的代价更低,但是我们还是建议在没有更好的原因的话,建议使用值传递。下面就值传递和引用传递做一些探讨。...

2022-07-30 12:11:40 2102

原创 GDB 源码分析系列文章五:动态库延迟断点实现机制

如果可执行程序使用动态链接生成,gdb刚启动时,若断点打在动态库的符号上,因为动态库还未加载,gdb会提示该符号找不到,并请求是否设置pending断点,这种断点即为延迟断点。若该符号在动态库中存在,调试过程中会命中该断点。本文结合gdb源码,分析gdb动态库延迟断点的实现机制。另外,对于gdb的事件循环机制和符号表相关实现机制可以参考往期系列博客,本文提到相关内容时不再赘述。............

2022-07-30 10:41:15 4595 2

原创 移动语义(Move Semantics)与 enable_if<>

移动语义(MoveSemantics)无疑是C++11最重要的特性,可以用于优化拷贝和赋值操作。本章将讨论下移动语义对模板设计的影响。

2022-07-17 21:34:06 2012 3

原创 gdb 调试技巧:定位程序卡死问题

程序卡住不退处,当然我这里的例子使用ctrl-c信号可以让程序退出,而我实际的程序是这里会卡死。不过这不是重点,重点是怎么知道程序卡死(或卡住)在哪里呢?当然这个简单的例子,你直接review代码就能看出,或者简单加几个printf就能定位出卡死的位置。遇到程序卡死不退处,可能不知道卡死在什么地方,如果程序非常简单,也许printf大法就可以很快定位。但是对于大型程序,尤其是一些框架程序,printf大法可能就力不从心了。最近遇到一个程序卡死的问题,借助gdb轻松定位,供大家参考。...

2022-07-16 09:50:35 9267 1

原创 Item 35: Prefer task-based programming to thread-based.

如果你想异步运行一个函数 ,你有两个基本的选择:基于线程的方法(thread-based)和基于任务的方法(task-based)。在比较二者优劣前,我们先介绍下 C++ 软件中线程的3个层次:基于任务的方法一般要优于基于线程的方法。 有返回值,可以代表任务的执行状态。基于线程的方法没有提供一个很好的机制获取返回值。而 返回的 对象提供了 方法可以获取到返回值。并且当 返回异常时,基于线程的方法直接抛出 ,而基于任务的方法可以根据返回值做异常处理。系统的软件线程是有限的,当请求创建的 多于系统提

2022-07-10 10:52:33 1960 1

原创 GDB 源码分析系列文章四:gdb 事件处理异步模式分析 ---- 以 ctrl-c 信号为例

gdb 处理的事件主要包括用户事件和目标程序事件。事件的处理可以分为同步模式和异步模式。本文介绍 gdb 事件处理的异步模式,并以 gdb 调试过程中 ctrl-c 信号为例展开介绍,其他信号事件的处理也是类似的。gdb 调试目标程序时,如果目标程序正在运行,此时你输入 ctrl-c 信号,gdb 将暂停目标程序。本文将结合 gdb 源码分析一下 gdb 如何处理 ctrl-c 信号。在前面的文章中,我们比较详细地介绍了 gdb 的事件循环机制,这里我们做下简单的前情回顾。gdb 在完成初始化后,即进入事件

2022-07-09 22:18:31 3959 5

原创 Tricky Basics of C++ Templates

这章将介绍关于模板的一些看起来有点棘手或者诡异的知识点,比如 的其他用途、零初始化、函数模板的字符串字面值参数等等。这些知识点在你常年的模板实践中总会遇到。在模板内部,可以使用关键字 指明一个标识符为一个类型。例如:使用 告诉编译器 是类内定义的一个类型。没有关键字 前缀的话,编译器会将 当作一个没有类型的数据成员,而 会被认为是一个乘法表达式。对于作用域内的内置类型(int,double,pointer,etc.),没有显示进行初始化赋值时,将会产生一个未定义的值。对于模板,如果模板类型

2022-07-03 16:51:22 2325

原创 可变参数模板 Variadic Templates

从 C++11 开始,模板可以有任意个模板参数,也即所谓的可变参数模板。定义一个函数 如下,用于接收不同类型的不同参数。 被称为模板参数包(template parameter pack), 被称为函数参数包(function parameter pack)。模板函数 首先打印第一个参数,然后递归调用自己打印剩余参数。为了结束递归,需要提供一个非模板类型重载函数,用于处理最后的空参数包。为了更直观地感受可变参数模板地递归处理过程,可以在以上 中插入 ,打印出函数的调用。当发生 调用时,输出如下:

2022-06-26 23:21:27 2382

原创 非类型模板参数 Nontype Template Parameters

除了类型可以作为模板参数,普通值也可以作为模板函数,即非类型模板参数(Nontype Template Parameters)。前一章使用的例子 使用的是标准库中的容器管理元素,也可以使用固定大小的 ,它的优势是内存管理开销更小,数组的大小可以交给用户指定。使用该模板需要同时指定类型和个数。 用于指定 的大小。非类型模板参数也可以有默认值。非类型函数模板参数也可以为函数定义非类型模板参数。也可以指定一个模板参数,由该参数之前的参数推断出其类型。或者保证传值的类型和指定的类型相同。非类型模板

2022-06-19 23:26:12 3339

哈尔滨工业大学编译原理课件(陈鄞主讲)

哈尔滨工业大学编译原理课件(陈鄞主讲)

2022-11-05

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

TA关注的人

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