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与集群交互, ...
随机推荐
- jenkins插件 查看job下次运行时间
文章来自:http://www.ciandcd.com 文中的代码来自可以从github下载: https://github.com/ciandcd jenkins插件next executions( ...
- 使用ThreadSanitizer线程检查工具
ThreadSanitizer又叫TSan,是一个检查线程Data Race的C/C++工具.它集成在新版的gcc和clang中,通过编译时加-fsanitize=thread,可以在运行时检测出Da ...
- mysql悲观锁总结和实践
使用场景举例:以MySQL InnoDB为例商品t_goods表中有一个字段status,status为1代表商品未被下单,status为2代表商品已经被下单,那么我们对某个商品下单时必须确保该商品s ...
- 错误The request sent by the client was syntactically incorrect ()的解决
http://www.cnblogs.com/xiandedanteng/p/4168609.html 这个错误是SpringMVC报出来的,见到它意味着html/jsp页面的控件名称 和 contr ...
- atitit.添加win 系统服务 bat批处理程序服务的法总结instsrv srvany java linux
atitit.添加win 系统服务 bat批处理程序服务的法总结instsrv srvany java linux 系统服务不同于普通视窗系统应用程式.不可能简简单单地通过运行一个EXE就启动视窗系 ...
- paip.java UrlRewrite 的原理and实现 htaccess正则表达式转换
paip.java UrlRewrite 的原理and实现 htaccess正则表达式转换 #---KEYWORD #-正则表达式 正则表达式 表示 非指定字符串开头的正则 排除指定目录.. 作者 老 ...
- Javascript实现计数器,定时警告和停止
<html> <head> <meta charset="utf-8"> <title>定时警告</title> < ...
- JSP内置对象总结
前几天学习了javaee中的jsp(Java Server Pages),即java服务器页面,其实就是在html里面写java代码. 一.概述前言 在总结九大对象之前,有必要先搞清楚几个概念:请求, ...
- shell日期的应用
#!bin/bash del_table() { #月初的第一天 month_first_day=`date +%Y%m01` #要删除的日期 last_7day_ago=`date -d " ...
- [推荐]PaaS技术知识贴
[推荐]PaaS技术知识贴 云计算PaaS技术与应用 http://wenku.baidu.com/view/08f77eefaeaad1f346933f20?fr=prin大型WEB网站架构深入分析 ...