- 博客(318)
- 收藏
- 关注
原创 如何理解内存序 memory order ?
为开发者提供了一种灵活控制原子操作内存顺序的方式,开发者可以根据具体的应用场景和性能需求,选择合适的内存顺序,在保证程序正确性的同时,尽可能地提高程序的性能。
2025-04-05 12:40:04
347
原创 如何理解缓存一致性?
缓存一致性是指在多处理器系统或分布式系统中,确保各个处理器核心或节点的缓存数据与主内存以及其他缓存中的数据保持一致的机制和过程。此时,数据仅存在于当前 CPU 的缓存中,与内存中的数据不一致。:缓存行中的数据仅存在于当前 CPU 的缓存中,且与内存中的数据一致。:当一个 CPU 修改一个共享的数据时,其他 CPU 的缓存行状态变为 Invalidated。:当一个 CPU 读取一个已被其他 CPU 缓存的数据时,状态变为 Shared。:缓存行中的数据存在于多个 CPU 的缓存中,且与内存中的数据一致。
2025-04-04 22:52:36
782
原创 Mimalloc论文解析:小内存管理的极致追求与实践启示
mimalloc 的内存分配器,它在有效平衡这些需求的同时,展现出显著优于现有分配器的性能优势,并专为需要内存分配器作为引用计数后端的语言进行了优化。
2025-03-22 18:37:05
920
原创 什么是 Cache Line?
例如,如果程序访问了某个内存地址,后续可能还会访问相邻的地址,这些数据已经预先加载到了同一个 Cache Line 中。例如,在 64 字节 Cache Line 的情况下,如果一个 8 字节的数据跨越了 Cache Line 边界(如从第 60 字节开始),则需要加载两个 Cache Line 才能完成访问。为了充分利用 CPU 缓存,数据在内存中的存储位置通常需要与 Cache Line 对齐。在多核系统中,Cache Line 的行为会对性能产生重要影响,尤其是在多线程编程中。
2025-03-20 19:38:09
772
原创 采用内存局部性分配有什么好处?
局部性分配通过提高缓存命中率、减少内存碎片、优化访问模式、提升多线程性能、支持延迟释放和简化内存管理,显著提升了内存分配器的性能和效率。而大名鼎鼎的 mimalloc 分片空闲列表的设计,看、就充分利用了局部性分配的优势,在多种基准测试中表现优异。
2025-03-09 22:40:07
908
原创 cpu 多级缓存L1、L2、L3 与主存关系
多级缓存(L1、L2、L3)和主存构成了现代 CPU 的内存层次结构,通过减少内存访问延迟和提高数据访问速度来优化性能。缓存的设计和性能对 CPU 的整体性能有重大影响,程序设计和内存分配可以通过优化缓存使用来进一步提升性能。
2025-03-09 20:57:04
1098
原创 C++ 11 中的并发多线程模式
并发:并发指的是计算机上的多个任务在同一时间段内完成。比如:我们在电脑上启动浏览器看 优快云 博客,同时又启动了音乐播放器播放音乐,用微信QQ 与好友聊天等等,这些看着是同时发生的,但是对于计算机的 CPU 来讲,却是一会运行这个程序,一会又运行另外一个程序,只不过切换的很快,对我们来讲,这是同时发生的。并行:并行指的是计算机上同一时刻同时运行多个程序。如果我们的电脑是多核 CPU,那前面的例子,多个程序是可以实现同一时刻运行多个的。c 语言中引入了 pthread 来实现多线程,但是并不好用;
2024-08-11 20:11:44
712
原创 C++ 学习系列 -- std::function 与 std::bind
std::function 是 c++ 11 的新特性 ,包含在头文件<functional>中,为了更方便的调用函数而引入。std::function 是一个函数包装器(function wrapper),可以包装任何可调用实体,包括如下几种:普通函数、函数指针、成员函数、静态函数、lambda 表达式 与 仿函数对象。std::function 对象实例可以拷贝与移动,可以使用指定的调用特征来调用目标元素。
2024-01-20 17:27:51
2400
原创 C++ 学习系列 -- tuple 原理
在 tuple出现之前,c++ 中的容器,序列容器:vector、deque、list ,关联容器:set、map 等,所存储的元素类型都是单一的(map 的 所有的 key 类型是相同的, 所有的 value 类型是相同的 )。如果我们有这样一个需求,需要一个容器或者说用着类似于容器的一个东西,可以存储不同类型的元素,上面的容器是无法满足我们的需求的。考虑到如此,c++ 为我们提供了 pair 类,但是美中不足的是,pair 只能存储两个元素,若是存储两个以上的元素呢?pair 就帮不了我们了。
2024-01-07 14:20:41
1246
原创 C++ 学习系列 -- C++ 中的多态行为
虚继承的目的是为了表明某个类的基类是可以被这个类的所有派生类共享,这个基类也被称作虚基类(Virtual Base Class),上述代码中的 class AA 就是 class BB 与 class CC 的虚基类。不管虚基类在派生类中出现多少次,最终在派生类中都只有一份虚基类的成员变量与成员函数。
2023-12-24 10:59:04
404
原创 C++ 学习系列 -- 模板 template
C++ 为什么引入模板?我的理解是:C++ 引入模板的概念,是为了复用重复的代码,当某些代码除了操作的数据类型不同以外,其他逻辑全都相同,此时就适合采用模板的方式。定义模板类或者模板函数时,只是定义了一个代码的架子,使用时需要配合上实际的数据类型,数据类型可以是基本数据类型也可以是用户自定义的类型。官方一点的说法:所谓模板,实际上是建立一个通用函数或类,其类内部的类型和函数的形参类型不具体指定,用一个虚拟的类型来代表。这种通用的方式称为模板。
2023-12-16 00:03:31
333
原创 C++ 学习系列 -- conversion function
在 c++ 编码中,我们可能遇到要将类 A 转为 类 B 的情况,此时就可以定义类 A 的转换函数将其按照一定规则转换为 类 B;转换函数无返回值,是一个已定义的类,包括c++基本类型 int、double 等,也包括事先定义过的类。这里介绍一下隐式转换的知识点:所谓隐式转换,由编译器私下进行的类型转换,该转换不需要使用者干预。当一个值拷贝给另外一个兼容类型的值时, 往往会发生自动转换。
2023-12-12 23:13:50
186
原创 C++ 中的内存分配 -- new 与 delete
函数的函数原型为:void* malloc(unsigned int size),它根据参数指定的尺寸来分配内存块,并且返回一个void型指针,指向新分配的内存块的初始位置。如果内存分配失败(内存不足),则函数返回NULL。free 函数原型为:void free (void* ptr),用于将 malloc 分配的内存释放掉。那么在执行 new 与 delete 两个 expression 时,内部发生了什么呢?malloc 与 free 是 C语言中用于分配与释放内存的两个函数,两者配对使用。
2023-11-11 18:44:52
201
原创 C++ 中的仿函数 functor
***/作为拥有一个输入参数的仿函数常用基类,该类主要回答了两个问题:1. 该仿函数类的输入参数是什么类型:argument_type2. 该仿函数类的返回参数是什么类型: result_type。
2023-10-29 17:56:10
678
原创 C++ 学习系列 -- 标准库常用得 algorithm function
c++ 标准库中提供了许多操作数据结构:vector、list、deque、map、set 等函数,学习并了解这些常用函数对于我们理解 c++ 的一些设计模式有着重要的作用。
2023-10-28 23:34:14
337
原创 C++ 学习系列 -- std::list
list 是 c++ 中的序列式容器,其实现是双向链表,每个元素都有两个指针,分别指向前一个节点与后一个节点链表与数组都是计算机常用的内存数据结构,与数组连续内存空间不一样的地方在于,链表的空间是不连续的,链表是将一块块不连续的内存串联起来使用。正是由于链表的内存不连续这一特点,所以不能像数组一样,可以根据位置随机的访问每个元素,而链表我们压根不知道每个元素的实际位置到底在哪块内存区域。查找某个元素需要遍历整个链表,直到找到目标元素位置,时间复杂度是 O(n);
2023-10-06 18:29:22
3564
原创 C++ -- 学习系列 无序关联式容器 unordered_set 与 unordered_map(未完待续)
一 HaseTable 是什么?二 HashTable 底层原理与使用?三 无序关联式容器的底层原理1. set1.1 unordered_set1.2 unordered_multiset2. map2.1 unordered_map2.2 unoredred_multimap四 无序关联式容器的使用1. set1.1 unordered_set1.2 unordered_m
2023-10-05 22:13:08
137
原创 C++ -- 学习系列 关联式容器 set 与 map
c++ 中有两种容器类型:关联式容器与序列式容器(顺序容器)关联式中的容器是按照关键字来存储与访问的,序列式容器(顺序容器)则是元素在容器中的相对位置来存储与访问的。c++ 中的关联式容器主要是 set 与 map.
2023-10-04 00:39:57
250
原创 C++ 学习系列 -- std::stack 与 std::queue
两者均是 c++ 中的序列化容器,区别在于:std::stack 元素是先进后出std::queue 元素是先进先出。
2023-10-01 18:09:39
465
原创 C++ -- 学习系列 std::deque 的原理与使用
std::deque 是 c++ 一种序列式容器,其与 vector 类似,其底层内存都是连续的,不同的地方在于, vector 是一端开口,在一端放入数据与扩充空间,而 deque 是双端均开口,都可以放入数据与扩充空间。
2023-09-30 15:19:42
2109
1
原创 C++ 学习系列 -- std::vector (未完待续)
vector 是c++ 中一种序列化容器,与前面说的 array 类似,其内存分配是连续的,但是与 array 不同的地方在于,vector 在运行时是可以动态扩容的,此外 vector 提供了许多方便的操作,比如:插入、删除、查找、排序等。
2023-09-23 17:53:25
323
原创 C++ -- 学习系列 std::array 容器
array 容器是11 标准中新增的序列容器,简单地理解,它就是在 C++ 普通数组的基础上,添加了一些成员函数和全局函数。在使用上,它比普通数组更安全,且效率并没有因此变差。与数组一样,其底层存储空间是连续的。array 和其它容器不同,array 容器的大小是的,无法动态的扩展或收缩,这也就意味着,在使用该容器的过程无法借由增加或移除元素而改变其大小,它只允许访问或者替换存储的元素。
2023-09-17 15:29:42
744
原创 C++ -- 学习系列 static 关键字的使用
全局变量特点:全局变量默认是有外部链接性的,作用域是整个工程,在一个文件内定义的全局变量,在另一个文件中,通过 extern 全局变量名的声明,就可以使用全局变量。静态全局变量特点:全局静态变量是显式用 static 修饰的全局变量,作用域是声明此变量所在的文件,其他的文件即使用 extern 声明也不能使用。在函数中定义的静态变量仅仅初始化一次,且变量会存储到静态存储区,因此即便离开函数作用域也不会消失。
2023-09-10 15:37:18
383
原创 C++ 学习系列 -- 智能指针 make_shared 与 make_unique
c++ 11 中 引入了智能指针 shared_ptr,以及一个模板函数 make_shared 来生成一个制定类型的 shared_ptr。
2023-09-03 00:00:18
2714
原创 C++ 学习系列 -- 运行时常量 const 与 编译期常量 constexpr 介绍
C++ 中引入了 const 关键字,被 const 关键字修饰的变量其值不能修改,是只读的。
2023-08-31 23:21:17
471
原创 C++ 学习系列 -- string 实现
string是C++标准库的重要部分,主要用于字符串处理。这里我们自己实现一个简单版本的 string.
2023-08-20 18:37:30
274
原创 c++ 学习系列 -- 智能指针
C++ 程序设计中使用堆内存是非常频繁的操作,堆内存的申请和释放都由程序员自己管理。但使用普通指针,容易造成内存泄露(忘记释放)、二次释放、程序发生异常时内存泄露等问题等。另外,使用普通指针容易产生 野指针、悬空指针 等问题。所以 C++11 就引入了智能指针来管理内存。
2023-08-13 00:04:34
267
原创 C++ 学习系列3 -- 函数压栈与出栈
调用指令:在函数调用点,会发出一个调用指令(如call指令),将控制权转移到被调用函数的入口点。保存返回地址:调用指令执行前,当前函数的返回地址会被压入栈中,以便在函数执行完毕后返回到正确的位置。参数压栈:函数调用时,将函数的参数按照一定的顺序压入栈中。通常,参数从右至左依次入栈。保存寄存器值:在一些体系结构中,函数调用时需要保存一些寄存器的值,以便在函数执行完毕后能够恢复原始的寄存器状态。帧指针与局部变量压栈。
2023-08-12 19:37:54
1698
原创 C++ 学习系列 二 -- RAII 机制
RAII (esourcecquisitionsnitialization)是由c++之父Bjarne Stroustrup提出的,中文翻译为其含义是:用局部对象来管理资源的技术,这里所说的资源指的是操作系统中的内存资源、网络套接字等等;局部对象指的是定义在栈上的对象,其生命周期的管理是由操作系统完成的。
2023-08-12 17:19:21
446
原创 C++ 学习系列 1 -- 左值、右值与万能引用
在 T 是模板参数时,T&& 的作用主要是保持值类别进行转发,它有个名字就叫“转发引用”(forwarding reference)。因为既可以是左值引用,也可以是右值引用,它也曾经被叫做“万能引用”(universal reference)。可以延长右值的生命周期,右值的生命周期可以与右值引用变量相同。简单的说,左值可以放在等号的左边,右值可以放在等号的右边。中的引用部分,只获取其中的类型部分。是左值还是右值,最后只获取它的类型部分。左值可以取地址,右值不能取地址。为左值引用的左值变量,通过。
2023-08-06 23:01:48
355
原创 面试题 -- 找两个数之间的间隔距离
有这么一组数,.... 10 8 6 4 2 1 3 5 7 9。给定两个数 a 与 b,求 a 与 b 之间的间隔距离。
2023-03-17 16:13:34
131
原创 面试题 -- 设计实现稀疏向量的点积
1)设计一个数据结构来表示稀疏向量,空间需要比较紧凑。2)基于这个数据结构,实现稀疏向量的点积。0的数量 > 95%
2023-03-17 15:31:09
248
原创 LeetCode刷题系列 -- 239. 滑动窗口最大值
的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的。滑动窗口的位置 最大值。滑动窗口每次只向右移动一位。
2023-03-13 16:53:05
272
原创 LeetCode刷题系列 -- 429. N 叉树的层序遍历
树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。树的节点总数在 [0, 10^4] 之间。给定一个 N 叉树,返回其节点值的。(即从左到右,逐层遍历)。树的高度不会超过 1000。
2023-02-25 14:37:17
476
原创 LeetCode 刷题 -- 236. 二叉树的最近公共祖先
中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。所有 Node.val 互不相同。p 和 q 均存在于给定的二叉树中。树中节点数目在范围 [2, 10。一个节点也可以是它自己的祖先。
2023-02-25 14:23:32
187
原创 LeetCode刷题系列 -- 112. 路径总和
不存在 sum = 5 的根节点到叶子节点的路径。由于树是空的,所以不存在根节点到叶子节点的路径。的路径,这条路径上所有节点值相加等于目标和。树中节点的数目在范围 [0, 5000] 内。等于目标和的根节点到叶节点路径如上图所示。(1 --> 2): 和为 3。(1 --> 3): 和为 4。和一个表示目标和的整数。是指没有子节点的节点。
2023-02-23 21:41:11
354
原创 LeetCode 刷题系列 -- 901. 股票价格跨度
2.1 如果 最后栈为空,说明以前的每一天的价格都小于当期 price,那么 返回 index + 1 即可,同时将当前的 index 与price压入栈中。// 返回 4 ,因为截至今天的最后 4 个股价 (包括今天的股价 75) 都小于或等于今天的股价。例如,如果未来 7 天股票的价格是 [100,80,60,70,60,75,85],那么股票跨度将是 [1,1,1,2,1,4,6]。int next(int price) 给出今天的股价 price ,返回该股票当日价格的。
2023-02-15 18:06:13
666
原创 LeetCode 刷题系列 -- 402. 移掉 K 位数字
移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219。移掉首位的 1 剩下的数字为 200. 注意输出不能有任何前导零。位数字,使得剩下的数字最小。请你以字符串形式返回这个最小的数字。从原数字移除所有的数字,剩余为空就是 0。num 仅由若干位数字(0 - 9)组成。本身之外,num 不含任何前导零。给你一个以字符串表示的非负整数。
2023-02-15 17:24:31
456
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人