【深入理解C++11】第六章 提高性能及操作硬件能力

现在各类语言百花齐放,大多都有很高的开发效率、或者专用场合使用,但是性能方面C++程序通常会有不可比拟的优势。

C++11中我们可以进一步发掘程序运行性能。

6.1 常量表达式

例如:枚举类型值、数组大小arr[size]、switch-case要求的值,都需要的是编译器常量,可以通过constexpr 标志一个变量或者函数为编译期常量。

6.1.1 常量表达式函数

函数返回值类型前加上关键constexpr来修饰一个函数为常量表达式函数,但是也有一些要求:

  1. 函数体只能有单一的return返回语句。
  2. 函数必须有返回值。
  3. 在使用前必须应有定义(函数体)。
  4. return返回语句表达式中不可使用非常量表达式函数、全局数据,且必须是一个常量表达式。
constexpr int retConstexpr()
{
	return 1;
}

当然这个函数也可以用作各类模板中。

6.1.2 常量表达式值

下面2条语句有什么区别吗?

const int i = 1;
constexpr int j = 1;

区别就是编译器一定会给i产生数据,而j如果没有使用者,编译器可以选择不产生数据,仅当作编译期的值。

6.1.3 常量自定义类型

需要定义自定义常量构造函数才可以构造自定义常量类型。

6.1.4 常量表达式其他应用

6.2 变长模板

6.2.1 变长函数和变长模板参数

6.2.2 变长模板:模板参数包和函数参数包

6.2.3 变长模板:进阶

6.3 原子类型与原子操作

6.3.1 并行编程、多线程与C++11

C++11标准中最重要的就是增加了多线程的支持,而不必依赖第三方库。

6.3.2 原子操作与C++11原子类型

原子类型支持表如下:
在这里插入图片描述
也可以自定义原子类型:

std::atomic<T> t;

需要使用新的关键字_Atomic来完成声明。
另外自定义类型不允许有拷贝构造、移动构造以及operator=以防止发生意外。
例如:

atomic<float> af{1.2f};
atomic<float> af{af};	//无法通过编译

下面是不同原子类型支持的操作:
在这里插入图片描述
大多数原子类型都可以进行如下操作:
读取(load)、写(store)、交换(exchange)、比较并交换(compare_exchange_weak/compare_exchange_stronge)。这些操作都是可以避免多线程竞争的。
其中比较并交换封装了不同平台上的最高性能实现,无法用统一的高级语言表达。

6.3.3 内存模型,顺序一致性与memory_order

6.4 线程局部存储

 通常情况下每个线程会拥有自己的栈空间,但是堆和静态存储区(.data,.bss段数据,C++上也就是对应着全部/静态变量区)这些是共享的。
 多线程共享数据比较容易,但是一些全局的错误码,可能会因为不同的线程执行,而得到错误的结果,导致一些关键错误被隐藏了。解决的办法就是每个线程指定一个全局的errno信息,也就是TLS(thread local storage)化的errno。
 在C++11中使用thread_local修饰变量即可得到一个TLS化的变量。测试demo如下:

//不使用thread_local修饰
int  gVal = 0;  //多线程访问变量
mutex gMtx;

void fun()
{
    int i = 100000;
    while (i--)
    {
        ++gVal;
    }

    lock_guard<mutex> lock(gMtx);   //为了方便打印
    cout << "gVal :" << gVal << endl;
}
//使用如下
thread th1(fun);
thread th2(fun);
th1.detach();
th2.detach();

在这里插入图片描述

int thread_local gVal = 0;  //多线程访问变量
//...以下同上,查看结果

在这里插入图片描述

©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值