C++ Low level performance optimize 2
C++ Low level performance optimize 2
上一篇 文章讨论了一些底层代码的优化技巧,本文继续讨论一些相关的内容。
首先,上一篇文章讨论cache missing的重要性时,用了list做比较,目的并不是说list没有用,而是说明cache missing会对性能有重要影响。如果元素不多,并且对象复制的代价很大,那么list可能就是更好的选择。其次,这里讨论的大部分是编码时一些比较底层的技巧,当遇到性能问题时,应该先考虑是否能在高层改进算法,减少运算,实在不行,在考虑这类优化技巧。性能优化的挑战就在于没有完美的永远适用的方案,了解这些技巧让我们在优化代码时有更多武器,但最终选择哪个方案还需要更加实际情况,并且以profile的实际数据为依据来做。
1. Data Layout
调整数据布局是常见的优化手段,做此类优化时有几点需要注意:首先是内存占用,现代编译器默认大多以16或32位对齐,因此
struct BadLayout
{
int8_t i0;
int32_t i1;
int8_t i2;
}; struct GoodLayout
{
int8_t i0;
int8_t i2;
int32_t i1;
};
sizeof(Goodlayout) >= sizeof(BadLayout) 在vs2013默认对齐设置下,BadLayout==12 byte,GoodLayout==8byte。
其次,经常访问或者相关的数据应该放到一起,减少cache missing。Going native2013 Andrei Alexandrescu介绍了facebook做的重要性能优化就是把php代码编译为c++代码,而在代码转换中重要的一步就是根据数据的”hotness”重新布局。
struct BadLayout
{
auto user0_data0;
auto user1_data1;
auto user0_data1;
auto user1_data0;
}; struct GoodLayout
{
auto user0_data0;
auto user0_data1;
auto user1_data0;
auto user1_data1; };
最后,可维护性!这一点非常重要,对于一些生命周期较长的项目来说,把数据按逻辑组织更易于维护,减少潜在bug的重要性,如果性能差别不大,我通常更愿意让代码看起来好读J
2. Code cache
struct BitBool
{
bool b0 :;
bool b1 :;
bool b2 :;
} struct NormalBool
{
bool b0;
bool b1;
bool b2;
}
上次的例子中,这段代码比较有争议,让我们从时间和空间方面来分析。时间上,因为BitBool需要额外指令来访问元素,因此效率一定比NormalBool低,但差别非常小,几乎可以忽略。再看空间上,但从结构本身看,显然BitBool更小,但是由于访问元素需要额外指令,实际应用中,生成的代码一定比NormalBool多,读取访问的次数越多,生成的代码也越多(内联的结果),而代码也需要占用内存空间!!cache line中通常一半是代码,一半是数据。因此,不一定因为BitBool本身小就得到更好的cache。大部分文章在讨论cache missing时都只介绍了数据,而忽略了代码也需要占用内存,也会有cache missing。某些游戏引擎会在update entity时先把对象按照类型排序,就是为了减少代码的cache missing。
最后,这个例子的目的是让大家了解过度优化可能并不会带来性能提升,实际应用中两种写法的虽然有性能差距,但基本可以忽略。
3. more about bit field
上一个例子让我想起了bitfield另一个微妙的地方,假设f1和f2在两个不同线程中,考虑下面代码是安全的吗?
struct BitField
{
bool b0 : ;
bool b1 : ;
bool b2 : ;
uint8_t i0 :;
} BitField bf;
std::mutex mtx1;
std::mutex mtx2;
//thread 1
void f1()
{
mtx1.lock();
bf.b1 = somevalue;
mtx1.unlock();
}
//thread 2
void f2()
{
mtx2.lock();
bf.i0 = somevalue;
mtx2.unlock();
}
No!!!虽然代码可以通过编译运行,但却并不是线程安全的,因为b1,i0都属于同一快内存”单元”,因此根本无法生成只更新b1,但是不写入i0的代码!!实际上c++11明确指出了这种情况会导致race,临近的bit总是被当做一个”对象” :)
C++ Low level performance optimize 2的更多相关文章
- C++ Low level performance optimize
C++ Low level performance optimize 1. May I have 1 bit ? 下面两段代码,哪一个占用空间更少,那个速度更快?思考10秒再继续往下看:) //v1 ...
- Solr实现Low Level查询解析(QParser)
Solr实现Low Level查询解析(QParser) Solr基于Lucene提供了方便的查询解析和搜索服务器的功能,可以以插件的方式集成,非常容易的扩展我们自己需要的查询解析方式.其中,Solr ...
- zabbix监控redis多实例(low level discovery)
对于多实例部署的tomcat.redis等应用,可以利用zabbix的low level discovery功能来实现监控,减少重复操作. 注:Zabbix版本: Zabbix 3.0.2 一.服务 ...
- 使用Java Low Level REST Client操作elasticsearch
Java REST客户端有两种风格: Java低级别REST客户端(Java Low Level REST Client,以后都简称低级客户端算了,难得码字):Elasticsearch的官方low- ...
- Zabbix监控Low level discovery实时监控网站URL状态
今天我们来聊一聊Low level discovery这个功能,我们为什么要用到loe level discovery这个功能呢? 很多时候,在使用zabbix监控一些东西,需要对类似于Itens进行 ...
- ChibiOS/RT 2.6.9 CAN Low Level Driver for STM32
/* ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio Licensed under the Apache License, Version 2 ...
- Consumer设计-high/low Level Consumer
1 Producer和Consumer的数据推送拉取方式 Producer Producer通过主动Push的方式将消息发布到Broker n Consumer Consumer通过Pull从Br ...
- zabbix(10)自动发现规则(low level discovery)
1.概念 在配置Iterms的过程中,有时候需要对类似的Iterms进行添加,这些Iterms具有共同的特征,表现为某些特定的参数是变量,而其他设置都是一样的,例如:一个程序有多个端口,而需要对端口配 ...
- Elasticsearch java api操作(一)(Java Low Level Rest Client)
一.说明: 一.Elasticsearch提供了两个JAVA REST Client版本: 1.java low level rest client: 低级别的rest客户端,通过http与集群交互, ...
随机推荐
- HTTP权威指南阅读笔记五:Web服务器
Web服务器会做些什么: 1.建产连接:接受一个客户端连接,或者如果不希望与这个客户端建立连接,就将其关闭. 1)处理新连接 2)客户端主机名识别 3)通过ident确定客户端用户 ident在组织内 ...
- [C++] socket - 5 [API事件对象实现线程同步]
/*API事件对象实现线程同步*/ #include<windows.h> #include<stdio.h> DWORD WINAPI myfun1(LPVOID lpPar ...
- JPA 使用
本文以JPA+Hibernate 角色与权限示例说明. 角色实体定义: @Entity @Table public class Role { private long id; private Stri ...
- little skill---ping
一.ping简介 Ping是Windows下的一个命令,在Unix和Linux下也有这个命令. ping也属于一个通信协议,是TCP/IP协议的一部分. 利用“ping”命令可以检查网络是否连通,可以 ...
- nosql/nodejs基础
nosql定义:nosql--no only sql 目前流行的非关系型数据库:mongodb,redis,cassandra 非关系型数据库和内存存储hashmap数据结构有什么区别?hashmap ...
- atitit.ajax bp dwr 3.的注解方式配置使用流程总结.....
atitit.ajax bp dwr 3.的注解方式配置使用流程总结..... 1. 下载 dwr.jar 1M 1 2. 配置注解方式..web.xml 1 3. Class 配置 2 4. 测试 ...
- javaweb学习总结(二十三)——jsp自定义标签开发入门
一.自定义标签的作用 自定义标签主要用于移除Jsp页面中的java代码. 二.自定义标签开发和使用 2.1.自定义标签开发步骤 1.编写一个实现Tag接口的Java类(标签处理器类) 1 packag ...
- wicket基本控件使用笔记
Label new Label(“message”,”message content”); MutLineLabel new MutlineLabel(“message”, ...
- hdu 2191 多重背包 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
http://acm.hdu.edu.cn/showproblem.php?pid=2191 New~ 欢迎“热爱编程”的高考少年——报考杭州电子科技大学计算机学院关于2015年杭电ACM暑期集训队的 ...
- jmap命令详解(转)
1.命令基本概述 Jmap是一个可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本.打印出某个java进程(使用pid)内存内的,所有‘对象’的情况(如:产生那些对象,及其 ...