- 博客(91)
- 收藏
- 关注

原创 《C++ 并发编程实战》一些示例代码段
在线程中可能访问局部变量的引用或者地址,但是在执行过程中该变量会被释放,导致线程运行出错,比如下面的例子因为线程分离了,local_val就有可能被回收。直接的修改方式就是把detach改为join,这样只有等到线程使用完, local_val才会被回收。对于一个线程如果不将它分离(detach),那么就要记得对它调用join。问题是并不是每次都会记得,甚至记得了也不一定能调用成功,比如下面的示例:如果要确保会调用join,需要捕获异常 这样非常麻烦,因为需要对所有可能出现异常的地方都使用
2025-08-05 11:59:07
839
原创 cuda编程笔记(13)--使用CUB库实现基本功能
可以求数组所有元素的乘积;乘积Reduce没有提供接口,可以自己写一个可执行对象(仿函数类,lambda表达式等都可以)这里使用lambda表达式#endifif (res!}, 1.0f);// 分配临时空间// 第二次调用:执行乘积}, 1.0f);return 0;如果用VS,打开项目属性,在这里加:(用仿函数类就不用开启这个,如此即可)// 调用// 自定义规约操作该成员函数可以让我们实现自定义的规约操作参数含义input。
2025-08-07 21:31:19
727
原创 Boost.Asio学习(6):Boost.Asio搭配c++协程
回调风格协程风格参数通过回调函数传入直接用获取需要捕获外部变量协程帧自动保存局部变量错误处理要在回调里处理try/catch一次性处理。
2025-08-03 14:19:49
990
原创 cuda编程笔记(12)--学习cuFFT的简单使用
把信号从时域(time domain)转换到频域(frequency domain)。在图像处理中,FFT 用于:滤波(高通、低通)卷积加速(卷积定理:卷积 = 频域乘法)在信号处理中,FFT 用于:频谱分析(检测信号频率成分)滤波、调制。
2025-08-02 22:43:38
782
原创 Boost.Asio学习(5):c++的协程
C++20 协程和普通函数完全不同,编译器在看到协程时不会直接返回值,而是生成一个状态机对象(Frame)。协程的返回类型必须定义一个嵌套类型。编译器规则co_return;编译器会查找,并生成代码去:创建一个对象。调用它的,把结果作为协程的返回值。调用控制是否立即挂起。调用或处理co_return。就是协程的“大脑”,控制协程生命周期。它必须提供一组固定接口(编译器调用)。
2025-08-01 11:53:42
1019
原创 cuda编程笔记(11)--学习cuBLAS的简单使用
cuBLAS 是 NVIDIA 提供的 GPU 加速 BLAS 库;使用时需要#include <cublas_v2.h>如果使用VS,需要添加cublas.lib的链接;如果用命令编译,-l记得加上cublas类型:枚举类型作用:表示 cuBLAS API 的返回状态(错误码)。常用值:返回值检查(典型模式): cublasHandle_t 类型:指向 cuBLAS 库上下文的句柄(类似于会话)。作用:所有 cuBLAS 函数都需要它。cuBLAS 使用 上下文模型,通过 管理状态。生命
2025-07-31 21:34:11
1133
转载 Boost.Asio学习(4):实现一个c++11风格的完备的服务器
在中,我们介绍了Boost.Asio里的基本的读写api,并封装实现了服务器类和客户端类。我们基于此继续完善我们的逻辑。
2025-07-28 20:01:27
26
原创 cuda编程笔记(10)--memory access 优化
一个 warp(32 个线程)在同一指令中访问全局内存时,如果这些访问请求可以合并成尽可能少的内存事务(通常是 32、64 或 128 字节对齐的块),就叫。
2025-07-27 22:33:15
574
原创 cuda编程笔记(9)--使用 Shared Memory 实现 tiled GEMM
由于每次只能将(TILE_SIZE × TILE_SIZE)大小的矩阵加载进共享内存,而一块(TILE_SIZE × TILE_SIZE)大小的矩阵A区域和一块(TILE_SIZE × TILE_SIZE)大小的矩阵B区域,不一定能够完成C[i][j]的计算。红色区域是本Block负责的(TILE_SIZE × TILE_SIZE)的区域,而计算这些区域C矩阵的值需要用到如下A,B矩阵的区域。任务:给定矩阵 A(M×K),B(K×N),计算 C = A × B,得到矩阵 C(M×N)
2025-07-21 22:44:54
847
原创 cuda编程笔记(8)--线程束warp
CUDA 中的是 GPU 并行计算的,这些线程将以的方式同步执行同一条指令。SIMT 执行模型(Single Instruction Multiple Threads)Warp 内 32 个线程但每个线程可以对操作(类似 SIMD)每次由发出一个 warp 执行一个指令周期分支发散(Divergence)问题如果 warp 内线程执行了不同的分支语句,会导致这时 warp 会执行,实际上还是串行,称为优化建议:warp 内线程尽量走相同路径(控制流一致)使用warpSize辅助判断。
2025-07-17 23:14:15
807
原创 cuda编程笔记(7)--多GPU上的CUDA
在调用时,CUDA 会在主机申请一块页锁定内存再通过把这块主机内存映射为设备端地址空间中的指针;当 GPU 访问dev_a[i]时,会通过PCIe 总线从主机 RAM 中取数据,实现零拷贝访问。所以它虽然“看起来像显存指针”,但其实访问的是主机内存。下面用该机制重写cuda编程笔记(2.5)--简易的应用代码-CSDN博客里的矢量点乘#endifif (res!stride > 0;// 将每个 block 的结果写入全局内存//在cpu上分配内存。
2025-07-13 21:22:13
770
原创 Boost.Asio学习(3):异步读写
异步读写与同步读写一样,有读/写各有三种api,合计六种函数所有的回调类型都是: 返回值是void类型 参数是const boost::system::error_code&,std::size_t异步函数不会阻塞程序,只是执行一个注册步骤,读写在后台执行,执行完成后会调用回调函数参数 : 可发送的 buffer(如 ): 回调函数 ,表示写入状态和写入的字节数仅尝试写一次,系统底层调用 ,可能不写完;如果写不完,你要在回调中继续发剩下的;不自动重试,也不保证写满。(封
2025-07-10 22:02:55
762
原创 cuda编程笔记(6)--流
页锁定内存(pinned memory)是指不会被操作系统虚拟内存管理机制移到磁盘的主机内存它是物理内存中被“锁住”的一段区域,可用于GPU 的直接访问(DMA)和异步数据传输在操作系统中,主机内存通常是分页(pageable)管理的:普通内存(如malloc()得到的):是可分页的;如果内存长时间未访问,操作系统可能把它换出到磁盘(swap),释放物理内存。页锁定内存(如得到的):是不可分页的;它始终驻留在主机物理内存中,不能被 swap 掉。为什么这很重要?
2025-07-07 21:15:33
636
原创 Boost.Asio学习(2):同步读写
是一个函数模板,用于创建一个通用的 对象,可传递给 I/O 函数(如 , , , 等)。它返回的是 或 的对象,取决于你传入的参数是可写还是只读。 与 的区别 类型 权限 用途 举例场景 可写 读取数据(recv) 、 只读 写入数据(send) 、 只能传给读操作,如 ; 只能传给写操作,如 ;可以将多个 buffer 组成一个 buffer s
2025-07-04 18:13:11
1072
原创 cuda编程笔记(5)--原子操作
CUDA 中的指能在并发线程中的函数。它们避免了竞态条件(race condition),保证操作的,即多个线程对同一个变量的读-改-写过程不会相互干扰。__device__(即修改之前的值)。常用原子操作函数分类。
2025-06-27 23:07:12
451
原创 cuda编程笔记(4)--纹理内存
CUDA 中的是一种,它使用了来提升内存访问效率,尤其在图像处理、科学计算中,访问图像数据或二维数据区域时表现优异。纹理内存并不是一种“新的内存”,而是对显存(全局内存)中数据的一种,提供了更高效的数据访问模式(带缓存 + 插值支持),特别适合处理:图像、视频等有的数据访问(相邻线程访问相邻数据)纹理内存的优势:如果线程访问的数据具有(相邻线程访问相邻地址),纹理缓存就能大幅提升带宽利用率。如果你想要(比如图像中采样某个像素的中间值),纹理提供天然支持。
2025-06-17 23:04:29
1099
原创 《Linux C编程实战》笔记:epoll多路复用
epoll是 Linux 下提供的一种,全称是event poll,用于处理大量文件描述符的可读写事件,是select和poll的。:创建一个 epoll 实例;:注册、修改、删除感兴趣的文件描述符;:等待发生事件的文件描述符。epoll 支持和两种模式,更灵活高效。EPOLLET那到底哪些因素是提高性能的更大障碍?是调用select函数后常见的针对所有文件描述符对象的循环语句?还是每次需要传递的监视对象信息?只看代码的话很容易认为是循环。但相比于循环语句,更大的障碍是每次传递监视对象信息。
2025-06-17 16:22:29
720
原创 cuda编程笔记(2.5)--简易的应用代码
实现线程间的数据依赖(例如:前缀和、归约等并行算法)。所有线程都执行到这一点后,才会继续执行后面的代码。:每个 block 有自己独立的一份共享内存。保证共享内存中数据已经被所有线程写入或读取。是 CUDA 中的一个关键字,用于声明。如果vs识别不出的话,加上这些宏定义即可。:只在同一个线程块(block)中可见。:非常快,接近于寄存器速度(比全局内存。:同一个 block 中的所有线程。是 CUDA 中的一个。
2025-06-15 22:30:07
503
1
原创 cuda编程笔记(3)--常量\设备内存与事件
是 CUDA 中用于的关键字,其作用是在设备的。1.声明常量变量(在全局作用域)注意:这声明了一个存放在 GPU 常量内存上的全局整型数组constData,不可在设备代码中修改。2.在主机端初始化常量内存⚠️ 使用是唯一向内存赋值的方式。不能直接写。对比其他类型__device____shared__完整示例代码。
2025-06-12 21:43:29
926
原创 《Linux C编程实战》笔记番外:如何避免子进程成为僵尸进程
wait()waitpid()在这种情况下,子进程的,以便父进程将来可以获取其退出状态。这个进程已经“死了”,但还在操作系统中“留个壳子”,这就是“僵尸”。🔍 具体过程:子进程调用exit()或正常返回结束;内核将其状态设为ZOMBIE(僵尸);等待父进程来调用wait()或waitpid();父进程调用wait()后,内核清理子进程的 PCB(进程控制块),从而完全释放其资源。
2025-06-11 16:32:04
509
原创 《Linux C编程实战》笔记:多路复用
nfdsreadfdswritefdsexceptfdstimeoutnullptrtimeval在设置为{0, 0}:立即返回,不等待(轮询)设置为{5, 0}:等待 5 秒设置为nullptr它本质上是一个,最多能表示FD_SETSIZE个文件描述符。通常,也就是说最多能监听 1024 个 fd。select函数的功能相当于:当套接字上有事件发生时(如有数据到达),系统通知服务器进程告知哪个套接字上发生了什么事,服务器进程查询对应套接字并进行处理。
2025-06-03 15:28:23
733
原创 《Linux C编程实战》笔记:套接字编程
socket()创建 socketbind()绑定 IP+端口listen()设置监听状态accept()接受客户端连接并获得新 socket。
2025-05-30 14:31:55
1199
原创 为什么std::bind,std::thread传递引用时需要std::ref?如何自己实现一个简易的Myref?
这么做的好处在于MyWrapper对象的拷贝并不会修改它保存的指针,也就是一直指向i的那部分,在std:bind内部,_Args只是MyWrapper对象在传递,不管MyWrapper是否被去除引用,被不停拷贝,最终还是会执行f(MyWrapper 对象),结果和上面的例子自然是一样的,i能够被改变。于是_Mypair里的参数类型就是普通值,所以_Mypair里的i与我们传递的i是完全不同的副本,最后调用的f(i)修改的也并不是我们传递的i。最终i还是0,并不会改变i的值;
2025-05-30 11:37:50
218
原创 cuda编程笔记(2)--传递参数、设备属性
int aint b:两个通过值传递的整型参数。int *c:一个指针,指向 GPU 设备内存,用于返回结果。cudaMalloc。
2025-05-28 21:32:16
871
2
原创 CUDA编程笔记(1)--最简单的核函数
_global__ void kernel_name(parameter_list) { // GPU 上执行的代码 }__global__在 GPU 上执行由 CPU 主机代码调用:核函数的名称。:参数列表,可以传递普通数据指针(如设备内存地址)或标量值。元素用法示例定义方式启动语法内置索引变量blockIdxthreadIdxblockDimgridDim索引计算输出方式printf()同步函数。
2025-05-26 22:04:37
947
原创 使用CRTP实现单例
CRTP(Curiously Recurring Template Pattern,奇异递归模板模式)是一种在 C++ 中广泛使用的设计模式,利用了模板的特性来实现静态多态。它是一种静态多态的实现方式,不同于传统的动态多态(基于虚函数的多态)。CRTP 模式的核心思想是:类Derived作为模板参数传递给基类Base,使得基类能够访问派生类的成员或调用派生类的函数,而不需要使用虚函数。通过这种方式,基类在编译时就能知道派生类的类型,从而实现静态多态。下面以动物类为例子,说明CRTP如何实现静态多态。
2025-05-25 17:24:59
755
原创 《C++ Templates》:有关const、引用、指针的一些函数模板实参推导的例子
这种情况,T是int类型这种情况,T还是int类型这种情况,T还是int类型这种情况,T是int *而这种情况,T还是int * (因为int *const p的意思是p是一个指向int类型的指针,而且指针p的值不能改变,故该const是顶层const)故这种情况下T是const int *(int const *)类型顺便提一下,这种情况T依然是const int *,因为T是不会推导出引用的。
2025-05-07 22:44:41
505
原创 新版pycharm如何实现debug调试需要参数的python文件
脚本形参填入参数,如:--arg1 value1 --arg2 value2。最后给文件打上断点,再点击调试按键,就可以调试了。script选择你要调试的python文件。
2025-04-05 20:53:03
285
原创 最新版pycharm如何配置conda环境
注意,conda的路径是你安装的conda的Scripts里的conda.exe;图片里环境显示是默认的,你应该选择刚刚新建myenv。首先在conda prompt里创建虚拟环境,比如。往里面安装点自己的包,比如。
2025-01-22 22:27:21
853
1
原创 力扣34. 在排序数组中查找元素的第一个和最后一个位置(经典二分)
我们如今已经找到了起始位置start,是满足nums[start]>=target的第一个点,我们是根据nums[start-1]<target原理找到的;寻找位置end也可利用nums[end+1]>target的性质,我们去寻找target+1在nums数组中的起始位置,减一即为end。此时left=3,确保了[0,left)区域所有元素小于target,那么[left,n-1]区域的元素自然大于等于target,而left也是题目要求的起始位置。以[5,7,7,8,8,10]为例。
2025-01-13 17:45:32
744
原创 最长连续公共子串
输入两个字符串 s1,s2。输出最长连续公共子串长度和最长连续公共子串。输入格式 一行,两个字符串 s1,s2 ,用空格隔开。输出格式 第一行输出最长连续公共子串的长度 第二行输出最长连续公共子串。如果不唯一,则输出 s1 中的最后一个。数据范围 1≤|s1|,|s2|≤100数据保证至少存在一个连续公共子串。输入样例: abcdefg qwercdefiok输出样例:4cdef1.暴力枚举枚举所有可能的长度,对比s1内所有该长度len的子串与s2中所有len长度的子串是否有相等的。
2025-01-10 10:39:38
650
原创 差分原理+练习
比如sub数组里的正数总和为6,负数总和为-4,那么经过4次操作,最后正数总和为2,负数总和为0,这种情况比如:{2,2,2,3,4}这时候再操作两次,就可以让sub数组的元素归0(sub[1]除外)(实际上最后的操作让sub[1]+=1,但是sub[1]在本题无意义,它不能反应工资是否相同)观察sub数组,题目提到一次操作可以使区间内的所有a都加1或减1,也即通过一次对[l,r]的操作,可以让sub[l]+=1且sub[r+1]-=1(也可能反之)最终的效果是sub[1]+=1,sub[4]-=1;
2024-06-06 22:47:38
1087
原创 单调栈原理+练习
首先用一道题引出单调栈首先画一个图演示山的情况:最暴力的做法自然是O(n方)的双循环遍历,这么做的思想是求出当前山右侧有多少座比它小的山,遇见第一个高度大于等于它的就停止。但是对于我们所求的答案数,可以换一个想法,对于5;7可以看到它。对于3;7,5可以看到它。对于4;7,5可以看到它。可以发现,即求左侧有多少比当前值大的山的个数,那么我们可以维护一个数据结构,使得每次加进来一个数,都保持递减的顺序,然后每次加入前,都计算它的size大小,进行累加。比如:一开始7进入;
2024-06-01 22:19:25
794
原创 力扣204.计数质数(线性筛)
假设不中断,对于i*primes[j+1]这个合数,它被primes[j+1]这个质数标记.但实际上,它的最小质数因该是primes[j],因为当i' =(i/primes[j])*primes[j+1]时,i' *primes[j]==i*primes[j+1],可知它因该被primes[j]这个质数标记。线性筛我之前的题解已经涉及到,但是讲的实在太差了我自己回看都看不懂,于是通过这道题重新回顾线性筛。(p,q等都是质因数,n,m是指数),其中一定会有一个最小的质数,我们的目的是要标记一个合数。
2024-05-17 21:55:10
325
原创 力扣207.课程表
我们知道拓扑排序可以用来判断是否有环路,不过仅仅是判断环路也可以直接用dfs,不需要完全写出拓扑排序,毕竟拓扑排序相比dfs还是更复杂一些。如果是有环图,可以自己试一下,最后图里会剩下环,因为环上所有节点的入度都不为0,因此不会入栈。从0出发,进行一次dfs,假设路径是0-1-3-4,那么最后1,3,4会变成红色,0还是蓝色。最终,4个节点全部入了栈,因此cnt==n成立,该图是无环有向图。一开始只有0的度为0,所以0入栈,出栈时会执行这一段代码。那么就把从0开始的弧都删掉,并把弧所指向的节点的入度减1。
2024-04-08 15:37:02
489
2
原创 力扣323.无向图中连通分量的数目(dfs/bfs)
失败版,这是我最开始写出来的bfs代码,不过超时了,原因应该是遍历edges太费时了,因为edges存的时候是无序的,要找到我需要的节点就要遍历整个容器。所以改进的话就再建个邻接矩阵,这样找临边就方便许多。这道题按理说是一眼并查集的,不过深搜广搜也可以做。所以dfs也得加邻接矩阵。
2024-03-17 11:36:38
498
原创 《Primer C++》第五版习题:第八章
cin流的状态处于错误,比如eofbit,badbit,failbit。记得保存好自己的Sales_data,因为这本书可惦记这个类了。因为需要的是一个聚合类,所以不应该使用类内初始化。因为我们不会修改它们,所以定义成const。
2024-03-04 17:09:39
324
原创 《Linux C编程实战》笔记:共享内存
由于本人要考研了,播客可能不会再长更。这本《Linux C编程实战》其实也差不多完结了,还剩网络编程章节没有讲,我肯定是没时间讲了,可能考研失败了会回来继续。《Primer C++》的课后题还有第八章的存货,后续章节只能随缘更新。Qt部分真烂尾了,写Qt项目的注释实在太累了。最有可能更新的部分是力扣题讲解,因为写来准备复试上机。最后祝大家,也祝我一切顺利。
2024-03-02 14:35:15
1215
1
空空如也
virtualbox虚拟机显示问题
2024-01-30
TA创建的收藏夹 TA关注的收藏夹
TA关注的人