- 博客(45)
- 收藏
- 关注
原创 GPT-2 分析与实现
预处理之后,有5类参数:blocks (transformer层的参数), b,g(输出层的final_norm shift/scale), wpe (嵌入层的Positioning embedding layer), wte(嵌入层的Token embedding layer和输出层线性层out_head)。一般来说,当我们模型的输出每一维有50257个元素,每个元素代表该词元ID的概率,找到最大概率的那个词元,我们就可以认为该词元就是我们要预测的word。以后有机会在细看吧。,选出概率最大的k个元素。
2025-10-06 15:21:40
851
原创 Flash attention分析与实现
1、GPU 中计算时,一般是把数据一块一块(Tiling)地加载到 shared_memory(即 on-chip SRAM),然后再计算。Flash attention里面用了分块,就是说,expsum()现在不是当前元素根据前一个元素来计算,而是当前块根据前一块来计算。对每一行做softmax, 求最大值和logsum, 然后用它们更新O_ij (之前block累积的softmax x V的值)。计算当前块的softmax x V的值,并把它们累加到之前的O_ij。里面的sumexp是l(x)
2025-10-06 15:06:02
832
原创 GPU 优化 - tensor core 用swizzle 解决bank conflict
所以,一个16x16x16的矩阵乘法里面每个矩阵被分成4个8x8 load 操作,如果没有padding的话,会产生bank conflict. 下面所有的图里面,同一个颜色代表同一个warp一轮要访存的元素组,里面的值代表共享内存的bank ID。如下图,我们在把矩阵从global memory load 到shared memory的时候,把数据8x8矩阵下面四行数据掉个位置,这样在同一warp去访存的时候,里面的元素不就在不同的bank里面嘛。上面介绍的博客,介绍了一种统一的写法下·
2025-09-02 20:49:04
533
原创 GPU 优化-用 tensor core实现5G Massive MIMO 64x64
本文探讨了64x64天线均衡器的实现方案,比较了ARM和GPU上的性能优化。重点分析了接收信号Y=HX+N的均衡处理,其中H为64x64信道矩阵。通过求逆得到均衡矩阵G后,采用X=GY+N0进行信号恢复。文章特别关注了GPU上使用tensorcore的优化效果,并考虑了G矩阵的动态变化特性(每4个元素共享同一矩阵)。同时讨论了接收信号Y的维度问题(通常273x12x14),为后续优化步骤奠定了基础。
2025-08-06 22:52:43
396
原创 gpu 优化 - 256QAM
同样,256qam 做完之后的t1时刻,应该发动D2H的memory copy. 但是stream 0的D2H CUDA API 还没到,这时候要等改API被launch 才会触发D2H.接收端,接收N/8的复数序列(c0c1…),要把它解码到长度N 的uint8_t 的soft bit的序列。),要把它解码到长度N 的uint8_t 的soft bit的序列。以下是接收端的256qam从复数到soft bit的转换公式,显而易见的是有很多的分支, anyway, 让我们看看如何一步一步去优化它。
2025-08-01 17:51:22
705
原创 Linux 内核学习 3b - 和copilot 讨论pci设备的物理地址在内核空间和用户空间映射到虚拟地址的区别
内核通过内存映射(memory mapping)将设备的物理地址映射到内核的虚拟地址空间中,而用户程序通过系统调用(如 mmap)将设备的物理地址映射到自己的虚拟地址空间中。ioremap() 函数的核心任务是将设备的物理地址转换为内核的虚拟地址,这样内核就可以使用普通的指针来访问设备的寄存器和内存。ioremap() 会将指定的物理地址范围映射到内核的虚拟地址空间中,并且标记这些内存区域为非缓存(uncached)或强制同步(write-through),以确保对I/O设备的访问是直接且一致的。
2025-01-22 20:58:38
1460
原创 Linux 内核学习 3a - 如何查看虚拟内存和物理内存,以及虚拟内存和物理内存之间转换
映射成功后,用户对这段内存区域的修改可以直接反映到内核空间,相反,内核空间对这段区域的修改也直接反映用户空间。最长见的操作就是文件(在Linux下设备也被看做文件)的操作,可以将某文件映射至内存(进程空间),如此可以把对文件的操作转为对内存的操作,以此避免更多的lseek()与read()、write()操作,这点对于大文件或者频繁访问的文件而言尤其受益。系统调用去访问那块物理地址,这里涉及到了两次拷贝,一次是用户空间到内核空间的拷贝,一次是内核空间到物理地址的拷贝;length:要映射的内存区域的大小。
2024-01-09 20:23:35
1186
原创 Linux 内核学习 3 - 虚拟内存和物理内存
这么做的好处是,操作系统为每个进程营造出一片独立的虚拟地址空间,使得进程与进程之间相互隔离,互不干扰的,解决了多进程同时运行时产生的内存地址冲突问题。经过本文前边内容的介绍,上图中的这个四级页表的遍历过程,我们已经非常的清楚了,我们可以明显的体会到整个地址翻译的过程需要的步骤还是比较多的,而。物理页面了,而根据程序的空间局部性原理,在不久的将来,进程只会访问与该物理内存页临近的页面,所以事实上,即使进程访问。访问内存的操作是非常非常频繁的,如果我们采用内核这种软件的方式对页表进行遍历,效率会非常的差。
2024-01-09 20:17:11
1889
原创 Linux 内核学习 2 - 用户程序如何被塞进内核进行调度?
fork里copy了父进程的信息,并激活task放到运行队列,当系统发生调度并获得执行机会时开始执行,但这时还不是hello程序,search_binprm_handler找到的是下面这样一个结构体,load_elf_binary才真正的加载了hello文件。load_elf_binary加载过程中会从ELF文件中获取text、data、bss等段的信息,加载完成之后hello的虚拟内存布局里就是下面这个样子,实际上所有进程的内存布局都是这样,在进程栈里保存了返回地址、argv、envp等信息。
2024-01-09 20:11:38
550
原创 Linux 内核学习 1 - 用户态和内核态
Linux使用 Ring 0 级别执行内核代码态代码时,Ring3 级别执行用户态代码,不使用 Ring1和 Ring2。处理器在Ring3级别执行时,无法执行 Ring0级别才能执行的某些 (如停机指令 HTLT等)指令,无法访问运行在Ring0级别才能访问的內存地址空间(包括代码和数据)。需要注意的是,运行在用户态和内核态,以及处理器的特权级别,与当前用户是管理员用户(root) 还是普通用户没有关系。所有用户启动的应用程序代码都在用户态还行,所有内核代码都在内核态运行,而不管代码是哪个用户启动的。
2024-01-09 19:59:42
655
1
原创 结合linux, 介绍PCI/PCIe
pci/pcie 设备的配置空间,构架,总线枚举,BDF分配, BAR初始化,TLP, 中断设置,以及驱动程序
2023-10-09 23:06:40
2090
1
原创 学习FreeRTOS(五) - 任务通信
队列解锁prvUnlockQueue()函数主要是判断在队列上锁期间是否有中断在读写队列,因为在队列上锁期间,中断来读写队列,只会拷贝消息(消息的出队或入队),并不会去操作xTasksWaitingToReceive ,xTasksWaitingToSend 这两个事件列表,只会记录(cRxLock或cTxLock加1),比如cTxLock+1表示队列上锁时,传输到队列(添加到队列)的入队项目数,则在队列解锁时则需要进行cTxLock次判断是否有任务在等待读取队列如果有则需要唤醒该任务。
2023-06-10 22:01:55
1870
原创 学习FreeRTOS(六) - 信号量
因此信号量也是为任务和任务、任务和中断之间通信做准备的,但是信号量一般用来进行资源管理和任务同步。同时也可以进行任务同步,即在一个任务(或中断)中告诉另一个任务它所等待的事件发生了,等到发生任务调度的时候,再切换到相应任务中,执行该事件发生的相关处理。FreeRTOS中的信号量有二值信号量、互斥信号量、计数信号量、递归互斥信号量,我们一般用二值信号量和计数信号量。当任务获取到信号量的时候才能开始使用被保护的资源,使用完就释放信号量,下一个任务才能获取到信号量从而可用使用被保护的资源。深度由第一个参数决定。
2023-06-10 22:01:20
378
原创 学习FreeRTOS(四) - 任务切换
而把一个挂起状态的任务恢复的唯一途径就是调用vTaskResume()或vTaskResumeFromISR() 函数,我们可以这么理解挂起态与阻塞态的区别,当任务有较长的时间不允许运行的时候,我们可以挂起任务,这样子调度器就不会管这个任务的任何信息,直到我们调用恢复任务的API 函数;• 运行(Running):该状态表明任务正在执行,此时它占用处理器,FreeRTOS 调度器选择运行的永远是处于最高优先级的就绪态任务,当任务被运行的一刻,它的任务状态就变成了运行态。在该异常的回调函数里执行任务切换。
2023-06-10 21:58:51
2205
原创 学习FreeRTOS(三) - 触发执行任务
在MCU中有硬件定时器,由外部晶振提供时钟输入源,经过时钟模块寄存器的配置,得到中断时间,一般都是中断模式触发时间中断,在中断服务函数中设置中断操作。而软件定时器事项功能和硬件定时器的功能是一样的,都是定时操作执行对应的服务,区别是软件定时器定时到了后执行的是回调函数,且在回调函数中不能执行阻塞任务的操作,如vTaskDelay()等。2、 测试出系统处理裕量(空闲任务只会在所有其它任务都不运行时才有机会执行,所以测量出空闲任务占用的处理时间就可以清楚的知道系统有多少富余的处理时间)。
2023-06-10 21:47:57
978
原创 学习FreeRTOS(二) - 任务创建
如果在这种轮询系统加上中断处理呢, 比如说,在main()中初始化中断,设置中断函数(interrupt service routine), 那样不就是一个简单的实时系统嘛?是的,在我之前碰到过的数字信号处理芯片(DSP)中,用的都是这种简单的机制,我们称之为前后台系统。[1] 如果configUSE_PREEMPTION设置为1,则RTOS调度程序将始终运行能够运行的最高优先级任务,因此调用taskYIELD()不会导致切换到更高优先级的任务。任务的描述名称,方便调试,不用的话可以设为。
2023-06-10 21:40:27
1147
原创 学习FreeRTOS (一) - 芯片启动
系统上电的时候,第一个执行的启动文件里面有汇编写的复位函数Reset_Handler(不同的芯片平台有不同的entry point). 复位函数最后会调用C库函数_main, 从而进入到用户编写的C语言的程序中。里面编译时用的link file的entry point 在不同平台是不同的,但是工作都是初始化处理器,配置各种堆栈(比如说起始地址和size),寄存器,interrupt 向量列表, 时钟等。具体里面每一步汇编指令,有什么作用,得要拿到芯片的配置指南才能一一走进去了。
2023-06-10 21:31:13
454
原创 异构系统中的IPC流程设计
项目中,一台多核ARM服务器,通过PCIe接口把一些计算量大的模块offload到以powerPC core为中控,另有fpga和dsp 协处理器的SOC芯片上。PowerPC cores 做为中控模块,它主要做和arm进行任务信息交互, 理解任务信息,并将任务分发给fpga和dsp协处理器,起到的是调度器的作用。
2022-09-24 15:49:40
803
原创 DSP vs CPU
1. 内存dsp小2. 系统架构, VLIW vs super scalar将一条指令分成若干个周期处理以达到多条指令重叠处理,从而提高cpu部件利用率的技术叫做标量流水技术. 超级标量是指cpu内一般能有多条流水线,这些流水线能够并行处理.在单流水线结构中,指令虽然能够重叠执行,但仍然是顺序的,每个周期只能发射(issue)或退休(retire)一条指令.超级标量结构的cpu支持指令级并行,每个周期可以发射多条指令(2-4条居多).这样,可以使得cpu的IPC(Instruction...
2021-09-23 21:23:05
1136
原创 Linear Feedback Shift Register
Linear Feedback Shift RegisterLFSR can be drawn in the following style.The above figure can be descripted as mod2(b(n+31) = b(n+3) + b(n+2) + b(n+1) + b(n)).Now my question is if I give an initi...
2020-11-20 22:19:00
250
原创 gdb利用core文件来定位segmentation error
1. make -g **- add -g option to enable gdb debug.2. ulimit -c unlimited- Enable coredump file to be created when segmentation fault occurs.3. Gdb ./bin core.xxxx- Get the core dump info. By the ...
2020-02-17 16:36:00
161
原创 信号量及一个简单的生产者消费者应用
信号量的使用是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)所拥有。当信号量的值为正的时候,说明它空闲,所测试的线程可以锁定而使用它。若为0,说明它被占用,测试的线程要进入睡眠队列中,等待被唤醒。信号量分为有名信号量和无名信号量。有名信号量,其值保存在文件中,可以用来进程间的同步。无名信号量,其值保存在内存中,主要用来线程间同步。有名信号量的创建:#include <se...
2019-11-01 16:40:00
156
原创 multi-thread的使用
1. 有了多进程,为什么要多线程?->许多应用中会同时发生多种活动,某些活动会随时间的推移而被阻塞,通过将其分解成多个顺序进程,程序设计模型会变得简单起来。多线程共享地址空间和所有可用数据的能力,是多进程无法做到的。->线程是轻量级的,它更容易创建和删除->在一些需要大量I/O处理和大量计算的情况下,拥有多线程允许这些活动彼此重叠进行,对程序性能提升是很明显的。一般用在...
2019-11-01 16:36:00
321
原创 滤波器的简单理解
滤波器就是把想要的频率外的信息给消除掉。我们只需要弄一个函数, 使得它在原信号对应频率上的位置为1,其他位置为0。这样频率上该函数和原信号相乘就可以保持想要的频率, 不想要的频率乘完之后为0(即滤波)。频域相乘就是时域卷积。所以,滤波器就可以通过原信号和一函数在时域卷积。...
2019-10-28 20:08:00
497
原创 ARM Neon指令集的一些简单的应用
Arm Neon UsagesEach Neon instruction detail can be searched in https://developer.arm.com/architectures/instruction-sets/simd-isas/neon/intrinsics?search=1. Load into Neon from data ptr/store into t...
2019-10-28 19:27:00
756
原创 离散傅里叶变换的一些理解和LTE基带信号生成的数学理解
离散傅里叶变换(DFT):快速傅里叶变换(FFT)是一种运用蝶形算子计算DFT的方法。下面是matlab实现代码:close all; clear;fs=200;N=256; %采样freq和数据点数n=0:N-1;t=n/fs; %时间序列% x=0.5*sin(2*pi*15*t); %+2*sin(2*pi*40*t); %实信号x=4*exp(j*2*pi*15*t...
2019-10-28 19:26:00
496
1
原创 DPDK 简介
DPDK(Data Plane Development Kit)是由6WIND,Intel等多家公司开发,主要基于Linux系统运行,用于快速数据包处理的函数库与驱动集合,可以极大提高数据处理性能和吞吐量,提高数据平面应用程序的工作效率。DPDK使用了轮询(polling)而不是中断来处理数据包。在收到数据包时,经DPDK重载的网卡驱动不会通过中断通知CPU,而是直接将数据包存入内存,交付应用...
2019-10-23 00:13:00
210
原创 Union的一个妙法
共用体在一般的编程中应用较少,在单片机中应用较多。对于 PC 机,经常使用到的一个实例是: 现有一张关于学生信息和教师信息的表格。学生信息包括姓名、编号、性别、职业、分数,教师的信息包括姓名、编号、性别、职业、教学科目。请看下面的表格:NameNumSexProfessionScore / CourseHanXiaoXiao501fs89.5YanWeiMin1011...
2019-06-18 17:22:00
159
原创 linux内存管理机制
做了这么年的linux c开发,经常碰到各种内存问题。这里结合网上资料做一下总结。一. 内存位置在C语言中,定义了4个内存区间:代码区;全局变量和静态变量区;局部变量区即栈区;动态存储区,即堆区;1. bss段 block started by symbol. 存储没有被初始化的全局和静态变量。2. data段 存储被初始化的全局和静态变量3. rodata段 常量变量。 rea...
2018-12-20 22:38:00
110
原创 DSP底层优化的几个规律
最近在做MMSE均衡器的实现,很耗时间。有如下建议1. loop 循环里面最好不要加各种判断If else. 可以制表代替。比如说下图代码所示,每个ue被分配一个rbmap, 每一次我们进入到该rb中,我们要判断它里面的每个re是不是rs re, 是不是pbch re, 是不是pss/sss re, 然后我们才能做接下来的动作。最死板的做法就是下面的代码,用了大量的if else, 每一次进入...
2018-12-19 00:10:00
190
原创 工作中遇到的难点
其实,也工作四年了,遇到的困难也挺多的,可惜没有一个好的习惯,把每次犯的错误记录下来,现在回想起来,这些记录,或者说是总结都是非常重要的,其一可以温故而知新,以后遇到同样的问题,可以快速的反应过来,查找原因;其二是和同事或者同行交流的时候,可以快速说出想说的,而不是临时去想词,磕磕绊绊还坏事,这样渐渐的别人对你的信任度会越来越低;其三是如果以后看到自己写了这么多东西,会不会觉得很有成就感呢。闲话...
2018-12-03 01:29:00
272
原创 找出数组里出现次数超过一半的数字
这是一个我刚刚毕业时候面试腾讯的面试题,当时我的答案是先排序,然后取中间的数,那么该数就是我们需要的数,但是,这种方法的复杂度不是线性的,所以说就被out了。从那之后,我一直在思考这个问题该如何被线性解决。慢慢地有一个想法,就是制作表,表的大小就是L* 2 (L是数组的长度)。表的每一行第一个元素是数组中的数字,第二个元素是该数字出现的次数。但是,接着想下去,就发现其实在loop数组的同时,我们...
2018-10-08 04:49:00
100
原创 CRC16 C语言实现
最近看到一个实现crc16的小程序,刚开始,不明觉厉,于是花了一个周末去know how。CRC(Cyclic Redundancy Check)循环冗余校验是常用的数据校验方法。 先说说什么是数据校验。数据在传输过程(比如通过网线在两台计算机间传文件)中,由于传输信道的原因,可能会有误码现象(比如说发送数字5但接收方收到的却是6),如何发现误码呢?方法是发送额外的数据让接收方校验是否正...
2018-04-24 00:35:00
401
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅