- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在使用 x86 英特尔机器和 Windows 7,以及 Visual C++(2005/2012 Express 版本)
我一直在玩对齐(我只是把它作为一种学习练习。)当然,我理解填充方面对类/结构大小的影响。我相信我理解它也更好地对齐,因为 CPU 指令的工作方式和期望数据。
我一直在看很多不同的资源,例如(有趣) c++ data alignment /member order & inheritance(以及维基百科等其他链接)http://en.wikipedia.org/wiki/Data_structure_alignment
一个可能受到影响的领域(我读到)似乎是性能,由于寄存器需要特定大小的数据,未对齐的数据可能会导致问题(参见维基百科)。
我写了一些代码,在其中创建了 3 个结构,所有结构都具有相同的成员,打包设置为 1 ,正常对齐,并且成员重新排列。这给了我 sizeof 8、10 和 12 的对象。我为每个运行了类似于以下的代码:
struct MixedData1
{
char Data1;
short Data2;
int Data3;
char Data4;
void operator() (MixedData1& md)
{
md.Data1 = 'a';
md.Data2 = 1024;
md.Data3 = 1000000;
md.Data4 = 'b';
}
};
typedef std::vector<MixedData1> MDVector;
int main(int argc, char* argv[])
{
MixedData1 md;
for(int count = 0; count < 10 ; count++)
{
{
std::cout << sizeof(md) << std::endl;
boost::timer::auto_cpu_timer t;
MDVector mdv(10000000);
std::fill(mdv.begin(),mdv.end(),md );
std::for_each(mdv.begin(),mdv.end(),md);
}
}
}
我对这些值并不感兴趣,所以 vector 中的每个元素都被初始化为相同的。无论如何,我得到的结果表明运行时间随着结构的大小而增加——即 pack(1)(8 字节)我得到最快的 0.08s,而正常对齐(12 字节)我得到最慢的 0.105。
我的问题是关于错误对齐的影响。我认为在我作为 C++ 程序员的 X 年中,我从未遇到过任何对齐问题,但当然它可能只是让我忽略了。
(1) 对齐在我的测试(编辑)中产生了影响(我相信)但是正如 Neil 发布的那样,这只是由于结构大小的差异。我尝试根据他的回复访问该成员,但我在那里没有看到任何实际效果……有更清楚的例子吗?有没有办法让我看到错位的显着影响?(2) 如果可能的话,有没有办法诱发错位引起的崩溃。
最佳答案
您的代码所做的只是测试处理器复制内存的速度。内存越大,复制越慢。结构中各个成员的对齐与复制速度无关,只有结构的大小很重要。
如果要查看对齐的效果,您需要编写实际访问各个未对齐结构成员的代码。例如,您可以编写一个循环来递增每个结构的 data3 成员。根据体系结构,编译器可能会意识到它必须使用不同的指令来执行算术;在 x86 上通常不是这种情况,编译器将生成看起来自然的代码,因为处理器能够处理未对齐的访问。一些处理器实际上可以以与对齐数据相同的速度读取和写入未对齐数据。一个简单的例子是 8088,因为它只有一个 8 位数据总线,所以所有 16 位指令无论如何都是使用两次加载来模拟的,但是最新的处理器大部分时间都在从缓存行中读取,因此唯一一次未对齐数据可能会有所不同是当数据跨越缓存行时。
如果你想通过错位引发崩溃,那么通常你需要在不同类型之间转换指针。然后,编译器可能并不总是意识到您的指针可能未对齐,并且不会为未对齐的访问生成正确的指令。例如,您可以尝试在强制转换的 char* 指针上调用 SSE 指令。
关于c++ - 数据(错误)对齐的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13223141/
我是一名优秀的程序员,十分优秀!