avatar

路漫漫其修远兮

并行计算课程复习笔记

本博客详细介绍了并行计算的基本概念和CUDA编程的应用。首先,讨论了并发与并行的区别,串行计算与并行计算的不同之处,并行计算的分类方法,包括计算模式、程序逻辑和应用角度。接着,介绍了Flynn分类法,解释了SISD、SIMD、MISD和MIMD的区别。然后,深入探讨了Amdahl定律,分析了其在提升程序性能中的作用,并通过具体例题展示了如何应用Amdahl定律计算加速比和所需处理器数量。 在CUDA编程部分,介绍了异构计算模型,分析了CPU和GPU的差异,强调了GPU在并行计算中的优势。讨论了CUDA线程的组织形式,包括线程、线程块、网格和核函数的概念。进一步讲解了CUDA的主机/设备编程模型,描述了不同函数限界符的作用及CUDA核函数的限制。 此外,博客还介绍了并行计算模型SIMT,GPU架构中的流式多处理器SM,内存模型及内存访问模式,强调了共享内存的使用及bank conflict的解决方案。通过示例代码,展示了如何在CUDA中实现图像翻转、数组相加、矩阵转置、方阵相乘、直方图计算、规约求和和TOP K问题。 最后,博客提供了实验指导,介绍了PI的三种求法、线程池的实现、矩阵相乘和转置的优化方法,并通过真题解析帮助读者巩固所学知识。

CUDA实现并行编程

本文通过编写CUDA核函数,以矩阵转置等5个问题为例,利用GPU众核对大规模问题的求解加速。首先,介绍了矩阵转置的算法流程,包括将矩阵存储到GPU内存、定义CUDA核函数、调用核函数执行转置、以及将结果复制回主机内存等步骤。代码实现中,利用共享内存优化访问全局内存,避免bank冲突。接着,讨论了矩阵相乘的核函数设计,强调了共享内存的使用和非方阵处理。代码示例展示了如何通过共享内存减少全局内存访问,提高性能。然后,介绍了统计直方图的实现,利用共享内存和原子操作提高效率。规约求和部分,提出了跨网格循环和交错配对法的优化策略。最后,探讨了TOP K问题的解决方案,利用CUDA规约计算高效排序和选择前K个元素。通过这些示例,本文展示了如何利用CUDA技术加速大规模数据处理和矩阵运算。

从机器学习的角度理解贝叶斯公式

贝叶斯公式是一种通过已知概率推理未知事件的工具,广泛应用于贝叶斯学派和机器学习的朴素贝叶斯分类器中。贝叶斯学派认为,没有什么是随机的,随机性只是信息不够的表现。通过贝叶斯公式,我们可以在事件发生后,利用事件发生前的各种概率进行推理。公式中的$P(c|x)$表示后验概率,是在已知某些条件下事件发生的概率,而$P(c)$是先验概率,是事件在未发生前的原始概率。$P(x|c)$是似然值,代表在条件c下观察到x的概率。$P(x)$是归一化常数,用于确保概率的总和为1。 在机器学习中,贝叶斯公式定义了朴素贝叶斯分类器,帮助模型通过最大似然估计来学习数据的分布。先验概率和后验概率是贝叶斯公式中的两个核心概念。先验概率是基于以往数据和经验得出的概率,而后验概率是在事件发生后,基于结果推测原因的概率。后验概率的计算依赖于先验概率,没有先验概率,后验概率无法计算。 贝叶斯公式和全概率公式之间的关系在于,全概率公式是由因求果,而贝叶斯公式是由果寻因。全概率公式总结了几种因素导致事件发生的概率,而贝叶斯公式则用于计算已知结果的情况下,各因素导致该结果的概率。通过这些公式,我们能够在不确定的世界中进行合理的推断和决策。

Pthread实现多线程编程

本文介绍了如何使用pthread进行多线程编程,主要通过两个实例进行讲解。第一个实例是通过多线程并行计算Pi值,利用莱布尼兹公式,通过数据划分的方式让多个线程分别计算部分数据以加速计算过程。为了避免多线程访问全局结果时产生冲突,使用了互斥量和信号量来组织线程有序地将局部结果累加到全局结果中。代码实现中,定义了一个BLOCK_SIZE常量,每个线程计算一块数据的和,并通过互斥锁保护全局变量sum的更新。第二个实例是基于生产者-消费者模式的线程池设计。线程池通过任务队列作为生产者和消费者之间的缓冲区,任务队列中的每个元素包含要执行的函数和函数参数。线程池的实现包括初始化任务队列、信号量、启动消费者线程,以及关闭线程池时等待所有线程运行结束。生产者通过thread_pool_enqueue函数将任务添加到任务队列中,并使用互斥锁和条件变量保护任务队列的操作。消费者通过thread_pool_worker函数从任务队列中取出任务并执行,确保任务队列为空时消费者线程会被阻塞,等待新任务的到来。最后,通过设计一个简单的任务输出任务id与线程id,并放到线程池中运行,展示了线程池的实际应用。通过这些实例,读者可以更好地理解多线程编程的基本原理和应用场景。

Essence of Linear Algebra

本文详细探讨了线性代数中的多个核心概念及其应用。首先,向量被描述为基向量的线性组合,强调了线性相关和线性无关向量在空间中的不同表现。矩阵被视为线性变换的表示,矩阵乘法则表示复合变换。行列式的几何意义在于变换后面积的变化,且行列式为零表示不可逆变换。逆矩阵用于解方程组,秩则表示变换后空间的维度。点积的对偶性揭示了向量与矩阵之间的深层联系。特征值与特征向量用于描述矩阵的变换特性,尤其在旋转和剪切变换中。基变换则涉及不同坐标系之间的转换。克莱姆法则提供了一种几何视角来理解行列式的计算。整体而言,文章通过几何和代数的双重视角,帮助读者更好地理解线性代数的基本概念及其在实际应用中的重要性。

算法基础模板

本博客涵盖了基础算法和数据结构的广泛主题,提供了详细的代码模板和应用示例。排序算法部分介绍了快速排序和归并排序的实现。二分查找部分展示了整数和浮点数的二分查找模板。高精度计算部分包括加法、减法、乘法和除法的实现。前缀和差分部分讲解了一维和二维的前缀和与差分。位运算部分提供了常用的位操作方法。双指针算法部分介绍了维护区间和次序的技巧。离散化和区间合并部分展示了如何处理区间和离散化问题。链表与邻接表部分讲解了单链表和双链表的实现。栈与队列部分介绍了栈、普通队列和循环队列的实现。KMP字符串匹配部分提供了求Next数组和匹配的模板。Trie树部分展示了字符串插入和查询的实现。并查集部分介绍了朴素并查集、维护size的并查集和维护到祖宗节点距离的并查集。堆部分提供了堆排序和模拟堆的模板。哈希部分介绍了一般哈希和字符串哈希的实现。搜索与图论部分讲解了DFS、BFS、拓扑排序、最短路径、最小生成树和二分图的算法。数学知识部分涵盖了质数、约数、欧拉函数、快速幂、扩展欧几里得算法、高斯消元和组合计数的内容。博弈论部分介绍了卡特兰数、NIM游戏和有向图游戏的理论。
0%