- 博客(551)
- 资源 (22)
- 收藏
- 关注
原创 OpenGL 进阶系列09 - 计算着色器
计算着色器(Compute Shader) 是 OpenGL 中的一种专门用于通用计算的着色器,独立于图形渲染管线。它允许在 GPU 上进行高效的并行计算,可用于科学计算、粒子模拟、物理引擎、图像处理等任务。计算着色器在 OpenGL 4.3 版本中引入,提供对 OpenGL Shading Language (GLSL) 的扩展支持。
2024-11-17 20:30:10
336
原创 C++ 并发专题 - 内存序介绍(Memory Ordering)
在 C++ 中,内存序(Memory Ordering) 是多线程编程中至关重要的概念,尤其是在处理共享数据时,确保线程间的同步与一致性是非常关键的。C++ 提供了一套机制,允许你控制不同线程对内存的访问顺序,从而保证数据的一致性。内存序的控制主要涉及 原子操作 和 内存屏障(memory barriers)。(松散顺序)解释:不对操作顺序做任何限制。操作可以在任何位置重排,甚至与其他操作无关。场景:只关心原子操作本身的成功与否,不关心其他操作的顺序。在这个例子中,threadA和threadB对x。
2024-11-15 18:12:29
810
原创 OpenGL 进阶系列08 - 天空盒实现
OpenGL 中的 Cubemap(立方体贴图)是一种将六个不同方向的图像(面)组合成一个立方体的纹理,用于模拟环境映射、天空盒、反射等效果。正面(+X)反面(-X)顶面(+Y)底面(-Y)左面(+Z)右面(-Z)每个面都是一张 2D 图像,通常它们是正方形的,且尺寸相同。
2024-11-14 22:45:57
248
原创 C++ 并发专题 - 自旋锁的实现(Spinlock)
自旋锁(Spinlock) 是一种用于线程同步的锁,它通过让线程不断地自我检查("自旋")来判断是否可以获得锁,而不是让线程在等待时进入阻塞状态。这种方式使得线程能够在锁被释放之前反复检查锁的状态,从而快速尝试获取锁,而不需要进行上下文切换。
2024-11-14 22:12:40
437
原创 OpenGL 进阶系列07 - 阴影贴图(shadowmap )
在 OpenGL 中,Shadow Mapping(阴影贴图)是一种常用的实时阴影技术,用于渲染物体的阴影效果。这种方法通过生成光源视角下的深度贴图,再在场景渲染时使用它来判断物体是否被遮挡,从而实现阴影效果。下面是实现 Shadow Mapping 的基本步骤和相关知识。
2024-11-11 23:32:08
613
原创 C++ 并发专题 - std::async 介绍
std::async是 C++11 引入的一种并发工具,用于异步执行函数并获取其结果。它可以用来启动一个异步任务,该任务会在后台运行,调用者可以在稍后获取任务的执行结果。二:std::async。
2024-11-11 23:04:54
247
原创 OpenGL 进阶系列06 - OpenGL变换反馈(TransformFeedback)
变换反馈(Transform Feedback)是 OpenGL 中的一项技术,允许你将顶点着色器的输出(例如变换后的顶点数据)直接传输到缓冲区,而不是将结果渲染到屏幕上。它在图形计算中非常有用,尤其在粒子系统、模拟、几何处理等场景中,可以用来获取顶点处理的中间结果,并将其用于后续的计算或渲染。
2024-11-07 23:44:50
628
1
原创 C++ 判断是不是平衡二叉树
(Balanced Binary Tree),具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。输入一棵节点数为 n 二叉树,判断该二叉树是否是平衡二叉树。在这里,我们只需要考虑其平衡性,不需要考虑其是不是排序二叉树。
2024-11-07 22:59:15
469
原创 C++ 并发专题 - 条件变量的使用
在 C++ 中,条件变量)是一种用于线程间同步的机制,主要用于在多线程环境中让一个线程等待某个条件满足后再继续执行。条件变量通常配合互斥锁(std::mutex)使用,保证了在访问共享数据时不会发生竞态条件。
2024-11-07 22:35:51
587
原创 C++ 并发专题 - 不变式与多线程
在C++中,“不变式”通常是指程序中某些必须始终成立的条件或者规则,破坏不变式(breaking Invariant Solved)的问题通常出现在并发编程中,当多个线程同时操作共享数据时,如果没有正确同步,可能导致数据不一致,进而违反了不变式。在多线程程序中,不变式是指那些在整个程序运行过程中始终需要保持为真的条件或属性。比如:1. 某个变量的值不能超过特定范围。2. 一个计数器的值应该是非负数。3. 某个状态应该在任何时候都保持一致。
2024-11-06 23:38:25
341
原创 驱动开发系列27 - Linux Graphics Kernel 内核调试环境配置
在驱动开发系列02 - 在ubuntu20.04 上配置 qemu/kvm linux kernel调试环境中我介绍过内核调试环境搭建,但这种方法在调试内核时不是很方便。特别是想调试启动过程,以及调试内核模块时比较困难,下面介绍另外一种内核调试的方法。即 busybox + initramfs + qemu + kernel 的方式,俗称内核调试环境四件套,这个调试环境可以较方便的调试内核启动过程,以及内核模块。BusyBox是一个轻量级的工具集程序,专为嵌入式 Linux 环境设计,但在其他系统中也常见。
2024-11-05 23:44:54
467
原创 C++ 并发专题 - 无锁数据结构(队列)
当我们在并发程序中使用队列时,通常会使用锁来同步推入(push)和弹出(pop)操作。我们会在执行推入或弹出操作之前加锁,并在函数结束之前解锁。然而,锁的使用会带来一些开销,包括创建和获取锁的成本。因此,如果我们能够完全避免使用锁,并仍然支持并发操作,那将是非常理想的。对于许多数据结构,如链表、栈和队列,我们可以借助原子操作中的比较并交换(CAS)来实现同步、无锁版本。在 C++ 中,它被称为。CAS 最初是 IBM 在 1973 年引入的 CPU 指令。
2024-11-05 22:18:04
594
原创 C++ 并发专题 - 无锁数据结构(概述)
无锁数据结构是一种在多线程环境中实现线程安全的结构,它允许多个线程在没有传统锁机制的情况下并发访问和修改数据。这种设计的目标是提高程序的性能和响应性,避免锁竞争和上下文切换的开销。
2024-11-01 21:44:06
607
原创 C++ 并发专题 - 原子等待(atomic wait)
原子等待是 C++20 引入的一个特性,主要用于多线程编程中。它允许线程高效地等待某个原子变量的值变化,而不是使用忙等待(busy waiting),这样可以减少 CPU 资源的浪费,提高程序的性能。原子等待的引入主要是为了提高性能和资源利用率,尤其是在以下场景中:减少上下文切换:传统的等待机制(如互斥锁、条件变量)常常涉及线程的阻塞与唤醒,这会导致上下文切换的开销。原子等待则允许线程在等待时进入休眠状态,避免了这些开销。
2024-11-01 21:26:45
584
原创 C++ 模板专题 - 静态分支(if)
模板元编程(Template Metaprogramming,简称 TMP)是一种在 C++ 中使用模板进行编程的技术,它允许在编译时执行计算、生成代码,提供类似脚本语言的功能。TMP 常用于生成高效的代码,避免运行时的计算开销。在高性能编程、类型处理、泛型编程等领域,模板元编程非常有用。模板元编程的一个使用场景就是进行编译器条件分支判断,称为“静态 if”。它允许我们在模板中根据条件编译选择不同的代码分支,而不需要实例化不符合条件的代码,这不仅可以提升编译性能,也可以简化模板代码逻辑。
2024-10-31 22:44:59
298
原创 C++ 模板专题 - 静态多态(CRTP)
CRTP(Curiously Recurring Template Pattern)是一种常用的 C++ 模式,用于实现静态多态性。通过 CRTP,可以在编译期确定子类类型,从而避免动态多态性带来的运行时开销。这种模式主要通过让基类接受派生类作为模板参数来实现。
2024-10-31 22:10:55
354
原创 C++ 模板专题 - 递归模板
在 C++ 中,递归模板是一种编程技术,允许在编译期通过递归定义模板,生成复杂的类型或计算复杂的表达式。递归模板通常用于元编程,允许在编译期进行类型生成、计算等操作,避免运行时开销。递归模板广泛应用于编译期常量计算、类型列表操作、类型萃取等场景。
2024-10-30 23:01:30
692
原创 C++ 模板专题 - 标签分派(Tag Dispatching)
在 C++ 中,Tag Dispatching 是一种编程技巧,主要用于在编译期根据不同的类型或特征选择不同的函数重载或代码分支。Tag Dispatching 借助类型标签(tags)进行函数调度,用于在模板中实现编译期的静态分派。这种方法特别适合在泛型编程中根据类型特性(如迭代器类型、数据结构特性等)选择特定的操作路径。
2024-10-30 22:25:05
423
原创 C++ 模板专题 - 模板参数类型推导
在 C++ 中,模板形参的类型指的是在模板定义中声明的参数类型。这些形参在模板实例化时被实际类型替代。理解如何根据实参类型推导模板形参的类型至关重要。左值(Lvalue):表示一个可被取地址的对象,通常指向内存中的一个位置。右值(Rvalue):表示一个临时对象,不能被取地址,通常是常量、字面量或表达式的结果。2. 其次解释下模板形参类型有哪些?T:普通类型模板参数T&:左值引用模板参数T&&:右值引用模板参数const T:常量类型模板参数。
2024-10-29 22:26:50
519
原创 C++ 模板专题 - 变长模板
C++ 变长模板(Variadic Templates)允许你定义接受任意数量模板参数的模板。这种功能在 C++11 中引入,非常灵活,常用于实现类型安全的容器、函数等。// 函数体。
2024-10-29 21:37:05
272
原创 C++ 模板专题 - 参数约束
除了使用SFINAE对模板参数进行约束之外,还可以使用概念(Concepts)来对模板参数进行约束,确保传入的类似满足特定条件。概念(Concepts)是C++20中引入的,概念是用于指定类型要求的一种机制。它们可以帮助你编写更清晰的代码,通过限制模板参数类型来提高类型安全性和可读性。requires关键字用于定义这些类型要求,是C++20中为概念(Concepts)引入的关键字。
2024-10-28 21:45:34
196
原创 C++ 模板专题 - SFINAE原理
SFINAE(Substitution Failure Is Not An Error)是 C++ 模板编程中的一个重要概念,它允许模板在类型替换时,如果发生失败,不会导致整个模板编译失败,而是让编译器忽略该模板,从而继续尝试其他可用的模板。这使得实现更灵活的模板和类型选择成为可能。模板参数替换:当编译器尝试实例化模板时,会替换模板参数。如果替换导致一个无效的类型或表达式,SFINAE 机制允许编译器忽略这个实例,而不会导致错误。使用条件:通常结合类型特征(如等)来控制模板的有效性。
2024-10-28 21:30:09
460
原创 LLVM - 编译器前端-llvm:IRBuilder 介绍
是 LLVM 中的一个重要类,用于方便地构建 LLVM 中间表示(IR)。它提供了一种高层次的接口,使得生成和操作 IR 更加简洁和高效。通过使用IRBuilder,开发者可以轻松地创建基本块、指令、函数等,而不需要直接操作低级别的 LLVM API。指令生成IRBuilder提供了一系列方法,用于生成各种类型的指令,如算术运算、逻辑运算、控制流指令(如条件分支、跳转等)和内存操作(如加载和存储)。上下文管理它与关联,确保所有生成的 IR 都在同一个上下文中,这对于内存管理和类型一致性至关重要。
2024-10-28 00:02:42
475
原创 LLVM - 编译器前端-llvm 基本块、指令、函数 的关系
在 LLVM 中,基本块、指令和函数是构建中间表示(IR)的核心概念,它们之间有着紧密的关系,首先了解下基本概念。
2024-10-28 00:02:35
677
原创 C++ 模板专题 - 类型擦除
C++ 中的类型擦除(Type Erasure)是一种技术,允许你在不暴露具体类型信息的情况下,通过统一的接口处理不同的类型。这种技术常用于实现泛型编程,特别是在需要支持多种不同类型的情况下,如容器、算法和接口。类型擦除通过隐藏类型信息,允许程序在运行时处理不同的类型。通常,这种技术涉及使用基类指针或模板来实现一种抽象,使得具体类型的细节在使用时被“擦除”。
2024-10-27 21:49:09
351
原创 C++ 模板专题 - 类型萃取
C++ 中的萃取(或类型萃取)是一种技术,主要用于从类型中提取特定的特性或信息,以便在模板编程中进行更灵活的类型处理。萃取通常通过模板和特化来实现,允许开发者在编译时确定类型的属性。类型萃取是指通过模板机制,提取和判断类型的一些属性,例如类型是否为指针、引用、数组等,或者提取类型的基础类型、大小等信息。特性检测:确定一个类型是否满足某种条件(如是否是整型、浮点型等)。选择性实现:根据提取到的类型特征选择不同的实现或算法。减少代码重复:通过萃取公共特性,减少代码中的冗余。
2024-10-27 20:39:52
394
原创 C++ 模板专题 - 表达式模板
C++ 表达式模板(Expression Templates)是一种编程技术,主要用于优化数学运算或其他复杂表达式的计算,特别是在数值计算库和高性能计算中。通过使用表达式模板,程序员可以减少不必要的临时对象创建,从而提高性能。通常,在C++中,普通的数学表达式通常会导致创建许多临时对象。C = A + B;// 可能会创建一个临时对象来存储 A + B 的结果在这个例子中,A + B会产生一个临时矩阵,然后再将其赋值给C。如果A和B是大型矩阵,这种临时对象的创建会造成性能损失。
2024-10-26 23:07:31
437
原创 C++ 在项目中使用vim
除了掌握 Vim 的基本操作,利用 Vim 阅读项目源码的方法同样重要,这对实际项目开发大有裨益。虽然现在有许多人选择使用 VSCode,但在某些环境中,可能无法安装 VSCode 或联网下载插件,这时使用 Vim 就显得尤为合适。此外,熟练掌握 Vim 可以显著提升阅读代码的效率,特别是在处理大型代码库时。本文将介绍一些实用的方法,帮助您更有效地使用 Vim 来阅读和理解项目源码。
2024-10-26 21:58:14
390
原创 C语言 - 语法和难点汇总
1.1 :C90 定义了几种基本数据类型,如intcharfloat和double。int a = 5;return 0;1.2 : C90 支持定义结构体,用于组合不同类型的数据。int age;return 0;1.3 : C90 提供了指针的使用,可以通过指针直接操作内存地址。int a = 10;return 0;1.4: C90 允许定义数组,支持一维和多维数组。i < 3;
2024-10-26 15:04:06
414
原创 C语言 - GNU C 和 ANSI C 之间的差异
基于 ANSI C 的扩展版本,由 GNU 编译器集合(GCC)实现,增加了许多 GNU 特有的功能。:标准化的 C 语言,确保了代码的可移植性和一致性。包括 C89 和 C90 标准。这个标准是对 ANSI C 的国际认可,确保了 C 语言在全球范围内的一致性。2. GNU C 支持可变长数组。3. GNU C 支持编译属性设置。1. GNU C 支持嵌套函数。4. GNU C 支持内联汇编。5. GNU C 支持灵活数组。
2024-10-26 10:50:07
635
原创 驱动开发系列26 - Linux Graphics 调试 mesa 的 glDrawArrays (二)
众所周知,Mesa 的 Gallium3D 是一个图形驱动框架,它将图形管线分层,以便支持多种硬件驱动和 API 实现。Gallium3D 通过抽象 GPU 驱动层,简化了 OpenGL、Vulkan 等图形 API 在不同硬件上的实现,提升了 Mesa 的可扩展性和硬件兼容性。Gallium3D 将 Mesa3D 分为几个主要层次,每一层都有特定的职责。这种分层设计将图形 API 的实现和底层硬件驱动逻辑分开,从而可以更高效地支持不同的 GPU 硬件。
2024-10-25 00:41:35
560
原创 驱动开发系列20 - Linux Graphics Xorg-server 介绍
X.Org Server 是由 X.Org 基金会管理的 X Window System (X11) 显示服务器的自由开源实现。客户端 X Window System 协议的实现以 X11 库的形式存在,这些库作为与 X 服务器通信的有用 API。有两个主要的 X11 库。第一个库是 Xlib,它是最初的 C 语言 X11 API;而另一个 C 语言 X 库 XCB 则是在 2001 年后创建的。还有其他较小的 X 库,既作为其他语言中 Xlib 和 XCB 的接口,也作为独立的小型 X 库存在。
2024-10-24 22:51:31
339
原创 OpenGL 进阶系列05 - OpenGL 图元重启(primitiverestart)
OpenGL 图元重启(Primitive Restart)是一种机制,允许你在绘制一个图元的过程中“重启”图元的序列,从而在一个绘制调用中使用多个不连续的顶点。这样,你可以将多个图形(如三角形、线段等)组合成一个单独的绘制调用,而不需要分别调用多次。1. glPrimitiveRestartIndex 介绍:它是 OpenGL 的一个函数,用于设置图元重启的索引值。这个索引值是在绘制图元时用于指示重启的特殊值。
2024-10-24 22:12:44
83
原创 驱动开发系列13 - Linux tasklet用法介绍
Tasklet 是 Linux 内核中的一种轻量级任务调度机制,通常用于在中断上下文中执行短小的任务。它们在软中断处理过程中被调用,允许将较长的处理工作延后到一个较低优先级的上下文中,以减少中断处理的延迟。Tasklet 的使用可以帮助开发者更好地管理系统资源,提高性能,同时也简化了中断处理的复杂性。
2024-10-23 22:34:40
343
原创 Vulkan入门系列21 - Raytracing 反射
本文介绍一下光线跟踪再图形渲染中的阴影和反射处理。它的原理如下:‘光线投射:从视点(相机)发射光线,遇到物体后,计算该点的光源可见性。阴影光线:从该点向光源发射阴影光线。如果阴影光线被其他物体阻挡,则该点处于阴影中,无法直接接收到光源的光。阴影判定:根据光线的可见性判断是否渲染阴影,这可以通过比较光线的起点和终点来实现。反射光线计算:当光线与物体表面相交时,根据反射法则计算反射光线的方向。反射方向与入射光线与法线的夹角相等。递归反射:反射光线可以进一步与其他物体相交,计算其颜色和亮度。
2024-10-23 21:29:20
415
原创 OpenGL进阶系列04 - OpenGL 点精灵
OpenGL 点精灵是一种渲染小型对象的技术(通常渲染粒子或光源),用于在3D场景中渲染小的、可缩放的点。它们通常用于表示粒子效果、光源或其他小物体。点精灵会根据视图和投影矩阵自动调整大小,使其始终在屏幕上保持一致的视觉效果。实现时,点精灵通常通过使用纹理和适当的着色器来增加视觉效果。
2024-10-22 21:22:31
173
原创 驱动开发系列25 - Linux Graphics 调试 mesa 的 glDrawArrays (一)
Mesa 是一个开源的图形库,提供对 OpenGL、Vulkan 和其他图形 API 的实现,从本文开始会分析OpenGL API的实现,调试Mesa的方法参见: 驱动开发01 - 编译与调试mesa库-CSDN博客 先从 glDrawArrays 开始,这个函数实现有些复杂,可能需要几篇文章参能分析完,在Mesa中,它的入口函数是 mesa_DrawArrays,先从这个函数开始:
2024-10-20 22:22:51
482
原创 渲染引擎实践 - UnrealEngine引擎中RHI实现分析
RHI(Rendering Hardware Interface)是 Unreal Engine 中的一个重要组件,负责处理与底层图形API(如 DirectX、Vulkan、OpenGL 等)的交互。它提供了一个抽象层,使得引擎能够在不同的平台和图形API上运行,而不需要为每种API单独编写渲染代码。抽象化图形API:提供统一的接口来调用底层图形API,从而简化了跨平台开发。资源管理:处理图形资源的创建、更新和销毁,比如纹理、缓冲区和着色器等。
2024-10-19 14:11:34
193
原创 C++ 一个反射的例子
在 C++ 中实现反射机制,虽然不像其他高级语言那样直接,但可以通过宏、模板和注册系统等技术来实现一个简易的反射系统。下面是一个完整的 C++ 反射机制示例,通过自定义类注册系统和宏定义,实现类的名称、属性、方法的反射。
2024-10-15 23:58:13
379
原创 驱动开发系列12 - Linux 编译内核模块的Makefile解释
6. 系统启动时自动加载 , 将模块名添加到 /etc/modules 文件中。5. 自动安装模块和依赖 sudo modprobe helloworld。1. 安装内核模块 sudo insmod helloworld.ko。7. 获取内核模块信息 modinfo helloworld.ko。2. 查看内核模块 lsmod |grep helloworld。4. 卸载内核模块 sudo rmmod helloworld。3. 查看内核日志 dmesg。8. 调试内核模块 printk。
2024-10-15 23:29:01
377
OpenGL Programming Guide (Red Book) 9th Edition Source Code
2024-10-07
Learn LLVM 17 A beginners guide to learnin - Kai Nacke.pdf
2024-07-08
Power and Performance Software Analysis and Optimization pdf
2024-04-09
计算机图形学经典书籍资料-渲染部分
2014-11-06
计算机图形学经典书籍资料-建模部分
2014-11-06
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅