在对齐大小的数组和非对齐大小的数组上速度不同
Speed different on aligned-size array and non-aligned-size array
我尝试对对齐大小数组和非对齐大小数组进行操作,但结果让我感到困惑,非对齐大小数组比对齐大小数组快,这是我的代码:
TimeMeter timeMeter;
const int N = 100000;
_Tp A[64];
_Tp B[65];
int szA = sizeof(A);
int szB = sizeof(B);
// Method 1
timeMeter.start();
for ( int n = 0; n < N; n++ )
{
memset(A, 0, szA);
}
timeMeter.stop();
printf("Method 1 Time usage = %f msn", timeMeter.span());
// Method 2
timeMeter.start();
for ( int n = 0; n < N; n++ )
{
memset(B, 0, szB);
}
timeMeter.stop();
printf("Method 2 Time usage = %f msn", timeMeter.span());
- 当
_Tp
为char
(8)时,方法1花费2.195ms,方法2花费2.175ms - 当
_Tp
为int
(32)时,方法1耗时13.313ms,方法2耗时5.987ms - 当
_Tp
为double
(64)时,方法1花费14.266ms,方法2花费11.304ms
您的基准测试无效,原因如下:
- 这里似乎没有检查对齐。你只是有两个不同大小的数组。此外,memset也不会太在意对齐,因为它在字节级别工作。
- 正如ildjarn所指出的,在如此小的内存上使用memset并不是很好。这实在是太快了,但这本身并不是一个大问题。
- …您没有使用您所设置的任何内存。优化器可以有效地消除对memset的所有调用,只保留一个。
- 当你不使用任何内存时,CPU实际上可能会做大量的重新排序/缓存,特别是在循环之间。 您的基准测试在许多操作系统上的运行时间接近时间片大小(您没有说哪一个,所以我猜在许多linux上的时间片是1ms)。这意味着操作系统切换开销可能会极大地改变你的测试结果。
- 数组是一个接一个分配的。cpu倾向于预测排序,因此这实际上可能会影响结果。试着改变循环的顺序,看看是否会有不同。
- 你没有说明你正在使用什么计时。许多计时器根本没有ms精度测试所需的分辨率,因此您可能会在结果中得到偏差。
类型必须在自身内部对齐,即char
必须在1字节边界上对齐,int
必须在4字节边界上对齐,double
必须在8字节边界上对齐。
要真正测试未对齐的访问,请尝试执行
_Tp* A = (_Tp*)((char*)(new char[num * sizeof(_Tp)]) + 1);
...
delete[] (_Tp*)((char*)A - 1);
此外,memset
将所有内容视为指向一系列char
的指针,这些指针永远不会对齐,因此无论您对数组做什么,您都无法让memset
进行未对齐的写入。
相关文章:
- 使用对象数组对 SFML 进行动画处理
- 将随机生成的数字添加到数组 + 对这些数组求平均值
- 在 64 位边界上对齐C++结构数组?
- 如何在VS2019中获取数组的任意对齐?
- 在 c++ 中将数据从未对齐结构数组移动到对齐结构数组
- 如何创建对齐的数组 c++ 数组?
- 使用字节数组具有单字节对齐方式的结构是否安全
- 使用动态数组对算法编译器错误进行排序
- 用另一个 constexpr 数组对成员数组进行大括号初始化
- 使用数组对对象的编译时多态性是否可行?
- UINT8数组对INT64的质量化失败,但应该起作用
- 使用值初始化的数组对零初始化数据
- 努力使用指针数组对结构数组进行排序.C++
- 对象数组对齐与 __attribute__aligned() 或 alignas()
- 不使用数组对结构进行排序
- 3 位的数组对齐
- 如何使用数组对类对象进行编号
- 在c++中使用数组对链表进行排序
- 在c++中,全局动态分配的数组对不同的输入给出不同的结果
- 2bit位域数组对性能和缓存效率的影响