1.1后续 Motivation for Move Semantics

1.节约资源

通过上一次讲解,我们发现程序做了很多无意义的拷贝,如果能直接将那些要销毁的元素直接给新的元素,那不省去了很多事情吗?
没错C++11的移动语义,就是干这个事情的

2.C++11

①createAndInsert(); 函数

#include <string>
#include <vector>

std::vector<std::string> createAndInsert()
{

std::vector<std::string> coll; //创建了一个vector 里面的元素是string

coll.reserve(3); // 在堆中预留了三个位置

std::string s = "data"; // 创建了字符串对象s

coll.push_back(s); // 插入string对象

coll.push_back(s+s); // 插入临时对象string

coll.push_back(std::move(s)); 
//插入了一个我们不在需要的字符串s 


return coll; // return vector of strings
}

②main函数 没有发生变化

int main()
{
std::vector<std::string> v; // create empty vector of strings
...
v = createAndInsert(); // assign returned vector of strings
...
}

我们看看哪里产生了优化?
①coll.push_back(s+s);
s+s会产生一个新的临时对象Temp,Temp是一个右值,下来怎么做?
不进行深拷贝了,直接把这个Temp指向的字符串拿过来,move过来,
Temp现在不指向它原有的字符串了,指向nullptr
然后Temp这个变量被销毁了
②coll.push_back(std::move(s));
在这个语句之后,我们再也没有用到s了,所以在函数结束之后,他会被析构,std::move就代表I no longer need this value here.
所以coll的第三个元素指向了s的字符串,没有进行深拷贝
③return coll;
在启用命名返回值优化的前提下(也就是不会产生一个右值),,直接move coll的字符串,给v

3.注意

①std::move(s) 仅仅标志着 这个是可以被移动的,并没有真正产生移动

     string s{ "123" };
     std::move(s);
     cout << s << endl;

输出的结果仍然是123
②在真正的进行move后,s的值是未定义的,取决于编译器

     vector<string> v;
     string s{ "123" };

     v.push_back(std::move(s));
     
     s.append("456");
     cout << s << endl;

输出的结果是456 VS2019的测试

PCIe (Peripheral Component Interconnect Express) 采用基于数据包的协议(packet-based protocol)主要是为了实现高效的数据传输、灵活性和可扩展性。在 PCIe 架构中,所有的数据交换都通过事务层数据包(Transaction Layer Packets, TLPs)来完成[^3]。这种设计有以下几个关键动机: 1. **高效的数据传输机制** PCIe 使用基于数据包的通信方式,可以将数据和控制信息封装在固定或可变长度的数据包中,从而实现更高效的数据传输。这种方式允许在数据传输过程中携带元数据(如地址、命令、校验信息等),使得设备之间能够更精确地交换数据[^3]。 2. **支持多路复用和并发操作** 基于数据包的协议支持多个事务并发执行,从而提高总线利用率。PCIe 利用数据包中的标签(Tag)和 ID 字段来区分不同的事务流(Traffic Class 和 Virtual Channel),实现多个请求和响应在物理链路上的交错传输,提升整体吞吐量[^3]。 3. **可扩展性和灵活性** 数据包格式的标准化使得 PCIe 能够适应不同的设备类型和通信需求。例如,PCIe 支持多种事务类型,包括内存读写、配置空间访问、消息信号中断(MSI)等,所有这些都可以通过不同的 TLP 类型来实现。此外,基于数据包的设计也便于协议的后续演进和功能扩展[^3]。 4. **错误检测与可靠性** 每个数据包都包含校验字段(如 ECRC 和 CRC),用于检测传输过程中的错误,从而提高通信的可靠性。这种机制在高带宽和低延迟的应用场景中尤为重要,例如在服务器和高性能计算设备中。 5. **降低硬件复杂度** 相较于传统的并行总线协议,基于数据包的串行通信减少了对共享地址/数据线的需求,简化了硬件设计。PCIe 的点对点连接和数据包路由机制也使得每个连接可以独立管理,进一步降低了系统复杂度[^3]。 ### 示例:PCIe 数据包结构 PCIe TLP 通常包括以下几个部分: - **Header**:包含操作类型(如 Memory Read、Memory Write)、地址、长度等信息。 - **Data Payload**:实际传输的数据。 - **ECRC(End-to-End CRC)**:用于端到端的数据完整性校验。 ```cpp // 简化的 PCIe TLP 结构体示例 struct TLP_Header { uint32_t fmt_type; // Format and Type uint32_t requester_id; // Requester ID uint32_t address; // Address uint32_t length; // Data Length }; struct TLP { TLP_Header header; uint8_t* data; uint32_t ecrc; }; ``` 综上所述,PCIe 采用基于数据包的协议是为了实现高效的并发数据传输、增强系统可扩展性、提高通信可靠性,并简化硬件设计。这种机制为现代计算机系统提供了高性能和灵活的外设互连能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值