ACE的CDR中的字节对齐问题
大家应该都知道计算机中间都有字节对齐问题。CPU访问内存的时候,如果从特定的地址开始访问一般可以加快速度,比如在32位机器上,如果一个32位的整数被放在能被32模除等于0的地址上,只需要访问一次,而如果不在,可能要访问两次。但是这样就要求一些数据从特定的地址开始,而不是顺序排放(中间会有一些空余的地址),这就是字节对齐。
而ACE CDR的估计也是为了加快速度,从而在CDR编码上默认也使用了字节对齐。所以在ACE的CDR编解码过程中,传入的参数地址最好是能符合字节对齐规则,否则可能会编解码错误。
ACE_OutputCDR构造函数会调用一个函数mb_align调整传入的地址参数成为地址对齐地址。但是其的调整函数ACE_ptr_align_binary不知处于什么考虑,不是按照机器的对齐长度而是采用的 ACE_CDR::MAX_ALIGNMENT(64bit,长度为8BYTPES)作为参数地址。那么ACE_OutputCDR的内部地址是按照8字节作为对齐的,但是ACE_InputCDR却没有将内部地址调整为模除64等于0的地址上,而只是调整为模除32(在32位机器上)等于0的地址。
void
ACE_CDR::mb_align (ACE_Message_Block *mb)
{
#if !defined (ACE_CDR_IGNORE_ALIGNMENT)
//如果使用字节对齐方式,使用最大的对齐方式调整内存。调整为模除64等于0的地址上。
char * const start = ACE_ptr_align_binary (mb->base (),
ACE_CDR::MAX_ALIGNMENT);
#else
……
}
使用一段简单的代码可以测试发现这个问题。
char *tmp_buffer = new char [2048];
//使用一个无法对齐的参数作为ACE_InputCDR,ACE_OutputCDR的参数地址,
char *tmp_data = tmp_buffer +1;
// output_cdr调整了对齐的起始地址为8字节的默认
ACE_OutputCDR output_cdr(tmp_data,512);
ACE_InputCDR input_cdr(tmp_data,512);
ACE_CDR::ULong cdr_long = 123;
bool bret =false;
//
bret = output_cdr.write_ulong(cdr_long);
// cdr_long 不等于123,而是一个错误无效数据。
bret = input_cdr.read_ulong(cdr_long);
其实如果编解码的BUFF都采用相同的对齐方式,那么理论上也不应该出现问题,最多是出现为了对齐而进行填补的空隙,但是这样能带来CPU的效率提升,也是好事。但是由于ACE_OutputCDR的一个地址调整。却可能导致编解码的BUFFER不一致,我不能肯定这到底是一个错误还是作者有他自己的考虑。
这个问题到5.6.1还存在。我已经提交了问题报告。
当然有一个方法解决这个问题。就是定义宏ACE_CDR_IGNORE_ALIGNMENT【注】,只要定义了这个宏,ACE就不会使用字节对齐处理CDR编码。使用这个方法的,编码占用空间会压缩一些,但效率上可能低一点(其实未必,因为为了字节对齐还要耗费一些计算时间),
【注】ACE不知道为什么在代码中使用两个不使用字节对齐的宏,一个是在CDR_Base.h CDR_Base.cpp 文件中使用的是ACE_CDR_IGNORE_ALIGNMENT,在CDR_Stream.cpp和CDR_Stream.h文件上使用的宏ACE_LACKS_CDR_ALIGNMENT。
我一般将两个宏都定义上。
ACE的CDR中的字节对齐问题的更多相关文章
- C语言中的字节对齐以及其相关处理
首先,我们来了解下一些基本原理: 一.什么是字节对齐一个基本类型的变量在内存中占用n个字节,则该变量的起始地址必须能够被n整除,即: 存放起始地址 % n = 0,那么,就成该变量是字节对齐的;对于结 ...
- C++中的字节对齐分析
struct A { int a; char b; short c; }; struct B { char a; int b; short c; }; #pragma pack(2) struct C ...
- C++中的字节对齐
本博客(http://blog.csdn.net/livelylittlefish)贴出作者(三二一.小鱼)相关研究.学习内容所做的笔记,欢迎广大朋友指正! 字节对齐 1. 基本概念字节对齐:计算机存 ...
- C语言中的字节对齐
下面这个篇博客讲解很好 http://blog.csdn.net/meegomeego/article/details/9393783 总的来看分三类: 1. 不加 #pragma pack(n)伪指 ...
- 关于sizeof与#pragma pack 以及网络上关于字节对齐的一点感想
工作中面试中对于字节对齐基本上是必考一个知识点,而很多面试是网络上上原题.基本上背一背就可以写正确,而关于4字节对齐我相信很多人也只是一个基本地了解,对于一些题目就感觉有问题,而且很多blog后面仍然 ...
- c++内存中字节对齐问题详解
一.什么是字节对齐,为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址 ...
- 关于C语言中结构体中的结构体成员导致的字节对齐问题
关于结构体的字节对齐是什么,就不赘述,再此附上一篇文章,介绍字节对齐:http://www.linuxsong.org/2010/09/c-byte-alignment/ 这里的结构体字节对齐的数据类 ...
- stm32中字节对齐问题(__align(n),__packed用法)
ARM下的对齐处理 from DUI0067D_ADS1_2_CompLib 3.13 type qulifiers 有部分摘自ARM编译器文档对齐部分 对齐的使用: 1.__align(n ...
- stm32中使用#pragma pack(非常有用的字节对齐用法说明)
#pragma pack(4) //按4字节对齐,但实际上由于结构体中单个成员的最大占用字节数为2字节,因此实际还是按2字节对齐 typedef struct { char buf[3];//bu ...
随机推荐
- css教程如何修改留言板程序
error_reporting(0);$conn = new com("adodb.connection"); $conn->open("driver={micro ...
- java 中的instanceof的用法
instanceof 运算符是Java.php的一个二元操作符(运算符),和==.>.<是同一类东西.由于它是由字母组成的,所以也是Java的保留关键字.它的作用是判断其左边对象是否为其右 ...
- Ubuntu彻底删除MySQL重装MySQL
1.删除 mysql sudo apt-get autoremove --purge mysql-server-5.0 sudo apt-get remove mysq ...
- 插入随机数到MySQL数据库
我们经常会遇到使用随机的问题,下面就是一种解决随机数的方法. 在构造测试数据时,我们需要对测试表插入随机数据.构造测试数据的方法如下,仅以update为例说明 步骤1:随机数的SQL函数为rand() ...
- windows下的mongodb分片配置
1. 分片服务器设置mongod -port 10001 -dbpath=F:/DbSoft/mongodb/rs_data/master -directoryperdb --shardsvr -re ...
- PHP 设计模式 笔记与总结(3)SPL 标准库
SPL 库的使用(PHP 标准库) 1. SplStack,SplQueue,SplHeap,SplFixedArray 等数据结构类 ① 栈(SplStack)(先进后出的数据结构) index.p ...
- pdfkit安装使用
centos 安装pdfkit1.先安装pdfkit依赖包 wkhtmltopdf 安装方式: # wget http://download.gna.org/wkhtmltopdf/0.12/0.12 ...
- Support vector machine
https://en.wikipedia.org/wiki/Support_vector_machine In machine learning, support vector machines (S ...
- php经典笔试题
五.基础及程序题(建议使用你擅长的语言:C/C++.PHP.Java) 5.写一个排序算法,可以是冒泡排序或者是快速排序,假设待排序对象是一个维数组.(提示:不能使用系统已有函数,另外请仔细回忆以前学 ...
- 低功耗蓝牙BLE [学习笔记]
手机设备会区分 "connecting" and "pairing" ,前者可以自动连接,后者则需要请求.BLE不再有pairing的麻烦,能直接连上目标设备, ...