- 博客(479)
- 收藏
- 关注
原创 并行计算之计算平台体系结构(流水线,异构处理器与异构并行)
我们就可以将任务进行拆解,到计算平台上的各个NUMA架构的CPU节点中,那么CPU与CPU之间进行MPI通信;而对于任意一个CPU节点,又可以拆解到多个核上,进行多线程任务拆解与执行;这样根据计算平台的体系,自上而下的进行任务拆解,直到整个任务的完成。
2023-09-04 22:44:35
601
原创 并行计算之OpenMP简介
面向多线程并行编码的编译指导语句,如for包含相应的函数接口库和runtime(运行时系统)omp_get_thread_num() //获取当前线程的线程编号omp_get_num_threads() //获取正在执行的并行部分的线程数,也就是要执行代码块的线程数omp_set_num_threads() //设置将要用于将来并行执行的线程数极大的简化多线程编码,支持Fortran,C和C++,从SMP实现开始,已经发布和发展了25年。
2023-09-04 22:43:09
320
原创 MPI之虚拟进程拓扑
在很多并行应用进程中,进程的线性排列不能充分的反映进程间在逻辑上的通信模型,通常由问题几何和所用的算法决定,进程经常被排列成二维或者三维网络形式的拓扑模型而通常用一个图来描述逻辑进程排列,此种逻辑进程排列为虚拟拓扑。拓扑是组内通信域上的额外,可选属性,它不能附加在组间通信域(inter-communcator)上,拓扑能提供一种方便的命名机制,对于由特定拓扑要求的算法使用起来直接自然方便。拓扑还可以辅助运行时系统,将进程映射到实际的硬件结构上。
2023-09-02 22:50:45
703
原创 MPI之数据打包和解包
MPI_Pack 和 MPI_Unpack 它们可以将式以便于传输,或者将二进制格式的数据解包成目标数据。这对函数通常用于在 MPI 应用程序中进行异构系统间的通信,即两个系统之间使用不同的二进制格式进行交互通信。
2023-09-02 22:31:31
914
原创 MPI之通信模式(标准,缓存,同步,就绪)
相对于 MPI_Send 函数,MPI_Bsend 不阻塞发送方,也不会复制消息缓冲区中的数据,而是将数据拷贝到MPI缓冲区中,MPI_Bsend 函数将立即返回,在MPI缓冲区中的消息稍后使用异步方式传输。该模式只有当接收进程的接收操作已经启动时才可以在发送进程启动发送操作(即是一种发送并立即返回操作),否则,当发送操作启动而相应的操作还没有启动时,发送操作将出错,对于非阻塞发送操作的正确返回,并不意味着发送已经完成,但对于阻塞发送的正确返回,则代表发送缓冲区可以重复使用。
2023-09-02 22:04:21
2185
原创 MPI之持久化通信句柄与非持久化通信句柄
在前面的文章中举了例子,我们使用MPI_Isend接口发送数据时,有个传出参数request,该参数是创建的通信句柄,使用该接口生成的持久化句柄,需要使用专用接口进行资源释放。
2023-08-30 23:09:22
405
原创 MPI之非阻塞通信中通信完成检测接口简介
个 MPI 请求组成的数组中的任一组请求是否已经完成,如果有已完成请求,则返回已完成操作的数量,并将这些完成操作的索引值存储在。个 MPI 请求组成的数组中的任一请求是否已经完成,如果有已完成请求,则返回其在数组中的索引值,并将该值存储在。个 MPI 请求组成的数组中的任一请求完成,返回值为完成操作的请求在数组中的索引值,将该值存储在。个 MPI 请求组成的数组中的所有请求是否都已经完成,如果所有请求都已经完成,则返回值。个 MPI 请求组成的数组中所有请求完成,返回值为。如果没有请求已经完成,则返回值。
2023-08-30 22:35:14
278
原创 MPI之MPI_Sendrecv接口以及空进程概念介绍
虚拟进程是不存在的假想进程,在MPI中的主要作用是充当真实进程通信的目的或源;引入虚拟进程的目的是为了在某些情况下,编码更顺畅;当一个真实进程给一个虚拟进程发送数据,或者从一个虚拟进程接收数据时,该真实进程会立即正确返回,如同执行可一个空操作;
2023-08-30 21:59:50
855
原创 MPI之MPI_Send&MPI_Recv阻塞接口及参数详解
MPI_Recv 函数是 MPI 标准中的一个阻塞函数,它将一直阻塞直到接收到来自指定源和标记的消息。返回值:函数执行成功,返回 MPI_SUCCESS。如果发生错误,则返回相应的错误码。返回值:函数执行成功,返回 MPI_SUCCESS。如果发生错误,则返回相应的错误码。
2023-08-29 22:53:05
3402
原创 并行计算之MPI简介以及基本通信案例(阻塞,非阻塞)
MPI_Test 函数的作用与 MPI_Wait 函数类似,都是等待一个请求对象进入完成状态,但 MPI_Test 函数是非阻塞的,即当请求对象尚未完成时,MPI_Test 函数会立即返回一个标志值,而不会阻塞当前进程的执行。通信域中的每个进程都有一个唯一的标识符(通信域内部的秩/等级(rank)),并可以通过指定目标进程的标识符来对目标进程进行通信。,在每个阶段中,数据沿着流水线被处理,不同的进程专门处理不同的阶段。拥有一个主进程,主进程作为任务的分配方,从进程执行任务,主进程负责管理数据的分发和接受;
2023-08-29 22:09:25
3580
原创 C++11 异步与通信之 std::async
std::async异步运行一个函数,将返回值保存在中。deferred延迟执行,当调用wait()和get()时,任务才会被运行,且不创建线程;async创建线程并执行任务,默认是此类型;同样的,调用get()方法获取对象时,也是阻塞等待的。
2023-08-13 22:03:48
551
原创 C++11异步与通信之 packaged_task
用于包装可调用目标(Callable)为一个对象,如lambda,普通函数,小括号重载等,用于异步调用。其返回值或所抛异常被存储于能通过 std::future 对象访问的共享状态中,和promise类似。将函数的调用与函数返回值的获取分开调用,这样就给异步提供很大的便利。猛的一看好像和std::bind绑定器作用相似,可惜std::bind返回的对象是同步的。
2023-08-13 21:07:34
258
原创 C++11 异步与通信之promise and future
std::promise 只能使用一次, void set_value(T &&val)设置传递值,只能调用一次 (保证结果单一)std::promise提供存储异步通信的值,再通过其对象创建的std::future对象异步获得结果。一个函数在线程A中调用,函数调用的结果希望在线程B中获取,不直接使用锁和条件变量,如何简单的实现?调用get()阻塞等待 promise set_value(T &&val))设置的值。
2023-08-13 20:04:44
262
原创 C++11之条件变量 condition_variable
条件变量(condition_variable)是一种同步原语,用于线程之间的协调。它允许一个或多个线程一起等待另一个线程的通知。条件变量依赖于互斥量(mutex),它被用来保护等待条件变量的共享数据,并在条件满足时通知等待的线程。线程通过持有互斥锁来进入等待状态并等待从其它线程中获得信号释放,该线程可以获取到mutex。当其它线程以notify_one或notify_all的方式发出通知,等待线程被唤醒开始尝试重新获取互斥锁。这意味着只有在持有互斥锁时才可以进行等待或接收条件变量信号。
2023-08-13 19:33:26
368
原创 C++17 之 scoped_lock 死锁避免神器
用于多个互斥锁的免死锁 RAII 封装器,是一种更加灵活和安全的互斥量管理方式。是一种独占互斥锁,它可以同时锁定多个互斥锁,并保证以原子方式获得所有互斥锁,从而有效避免死锁。它可以接受多个互斥锁作为参数,并在构造函数中自动锁定这些互斥锁。当对象出作用域时,它会析构并自动解锁所有已经锁定的互斥锁,确保互斥访问的安全性和正确性。
2023-08-12 23:20:20
609
原创 C++14 17共享超时互斥锁 shared_timed_mutex / 共享锁 shared_mutex
共享锁,也叫。比如,在多线程环境下,多个线程操作同一个文件,其中读文件的操作比写文件的操作更加频繁,那么在进行读操作时,不需要互斥,线程间可以共享这些数据,随意的读取。但是一旦有写操作,那么一定要进行互斥操作,否则读取到的数据可能存在不一致。
2023-08-12 21:29:30
1328
原创 C++11 之 递归锁 recursive_mutex
在一些业务场景下,线程在获取锁后还会多次获取该锁,且保证不出现死锁或者程序崩溃异常。简单地说,递归锁是一种在。
2023-08-12 17:39:28
1085
原创 视频基础知识简介
也称YCbCr, 其中Y信号表示明亮度(灰阶),UV的作用是描述影响色彩以及饱和度。举个例子,当电视机是黑白电视时,即使没有UV信号,也可以展示Y信号,只不过时是黑白的如果电视不是黑白电视,那么除了Y信号,UV信号也可以展示,显示的图像是彩色的。
2023-08-07 21:36:38
217
原创 详解C++特性之noexcept (C++11 C++17 C++20)
上面说到,noexcept()可以判断目标类型的移动构造函数是否可能抛出异常,那么我们可以先判断有没有抛出异常的可能,如果有,那么使用传统的复制操作,那么执行移动构造。实际上,这并不是最优解,因为很多自定义类型的拷贝构造也是很简单的,几乎不会抛出异常,我们还可以利用noexcept运算符的能力,判断类型的拷贝构造是否会抛出异常。判断类型是一个普通类型还是复杂的类型,如果是普通类型,返回true,则表示不会抛出异常,否则将表示可能会抛出异常。函数,则程序直接退出,否则跳转到处理异常的。在C++11前,使用。
2023-07-23 21:07:50
1579
原创 C++11之线程局部存储 thread_local
我们知道,在Linux系统中,子线程是通过复制来产生的,由于进程是资源分配的最小单位,那么,进程中的线程除了有自身运行时需要的一些栈空间,寄存器等资源,其余资源都是和其他线程共享的,这就会引入一些资源竞争的问题,为应用程序执行带来不确定性。而线程存储指的是一种特殊的内存机制,用于将数据存储在当前线程的私有内存中,这样线程就有自己私有的数据存储空间,不会被其他线程所干扰。实际上,线程局部存储早就出现,由于是一种特殊的内存机制,所以需要操作系统层面的支持。
2023-07-23 15:30:55
322
原创 0号进程,1号进程,2号进程
是一个内核进程,是所有进程的祖先,也叫做swapper进程。主要作用:执行start_kernel()函数,初始化内核需要的所有数据结构,激活中断,创建1号内核进程(init进程)。只有当没有可运行的进程的时候,才会运行0号进程,0号进程不是一个实实在在可见的进程,它是单用户,单任务的系统启动代码由0号进程创建的1号进程,pid=1,1号进程共享0号进程的所有的数据结构。1号进程一开始是内核进程,先执行init()函数完成内核初始化,然后调用exec()装入可执行程序init(),这样init就变成可
2022-06-26 14:58:45
2322
原创 容器适配器复习
实际上,容器适配器在工作中使用的不是特别多,所以对这些东西的个别细节难免有些遗忘,今天这里回顾一下。什么是适配器适配器类底层组合了已经有的容器对象,对外开发一些接口,这些接口实际上是对容器接口的封装,或者直接调用容器对象的方法。容器适配器没有自己的数据结构,没有自己的迭代器,实现全部依赖于底层的组合的容器。比如,template <class T,class Container = deque<T>>class stack{public: void pop() {
2022-05-30 20:55:01
147
1
原创 再聊C++多重继承之菱形继承
菱形继承的问题和内存布局class Base{public: Base(int){ std::cout << "Base()" << std::endl; }; ~Base(){ std::cout << "~Base()" << std::endl; };protected: int n;};class A : public Base{public: A(int a):Base(a){ std::cout <<
2022-05-14 16:16:42
352
原创 C++中如何定义指向类成员的指针
简单示例class Test{public: Test(){ std::cout << "Test()" << std::endl; }; void show() { std::cout << "show()" << std::endl; } static void fun(){ std::cout << "fun()" << std::endl; } int a; static int b;
2022-05-08 21:28:53
687
原创 再聊C++抽象类
什么是抽象类含有纯虚函数的类就叫做抽象类。抽象类不能定义对象,但是可以定义指针和引用。class Occupation{public: Occupation(){ std::cout << "Occupation()" << std::endl; }; //纯虚函数 基类给派生类预留的统一的接口,派生类必须实现 virtual void work() = 0;};再派生类中,纯虚函数必须实现,否则派生类还是一个抽象类:class Student : pub
2022-05-08 21:04:51
800
原创 C++中何时静态绑定,何时识别RTTI类型进行动态绑定?
静态绑定:编译时期就确定调用的是哪个方法,如模板,函数重载等动态绑定:程序运行时才确定调用的是哪个方法,即多态。何时静态绑定,何时识别RTTI进行动态绑定无论是基类指针(引用)指向基类对象,还是派生类指针(引用)指向基类对象,还是基类指针(引用)指向派生类对象,只要该指针调用的方法是一个虚函数,那么将发生动态绑定两要素:指针或者引用调用了虚函数。class Occupation{public: Occupation(){}; void show() { std::cout <&
2022-05-08 17:22:56
360
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人