【发布时间】:2012-07-24 18:19:46
【问题描述】:
我上了这门课,
方法一:
typedef float v4sf __attribute__ (vector_size(16))
class Unit
{
public:
Unit(int num)
{
u = new float[num];
v = new float[num];
}
void update()
{
for(int i =0 ; i < num; i+=4)
{
*(v4sf*)&u[i] = *(v4sf*)&v[i] + *(v4sf*)&t[i];
//many other equations
}
}
float*u,*v,*t; //and many other variables
}
方法2:
与方法 1 相同。除了方法 2 中,v、u 和所有其他变量都分配在预先分配在堆上的大块上,使用位置 new。
typedef float v4sf __attribute__ (vector_size(16))
class Unit
{
public:
Unit(int num)
{
buffer = new char[num*sizeof(*u) + sizeof(*v) /*..and so on for other variables..*/]
u = new(buffer) float[num];
v = new(buffer+sizeof(float)*num) float[num];
//And so on for other variables
}
void update()
{
for(int i =0 ; i < num; i+=4)
{
*(v4sf*)&u[i] = *(v4sf*)&v[i] + *(v4sf*)&t[i];
//many other equations
}
}
char* buffer;
float*u,*v,*t; //and many other variables
}
但是,方法 2 的速度要快 2 倍。这是为什么呢?
大约有 12 个浮点变量,num 为 500K。 update() 被称为1k 次。速度不考虑内存分配。我这样测量速度:
double start = getTime();
for( int i = 0; i < 1000; i++)
{
unit->update();
}
double end = getTime();
cout<<end - start;
这在方法 2 中快了大约 2 倍。
编译器选项:gcc -msse4 -o3 -ftree-vectorize.
一级缓存为 256K,内存为 8GB,页面大小为 4K。
编辑:更正了方法2中分配变量的错误。所有变量都正确分配在不同的部分。 处理器是 Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz
编辑:在此处添加源代码 - Source。方法 1) 给出 69.58s,方法 2) 给出 46.74s。虽然不是快 2 倍,但它仍然很快。
【问题讨论】:
-
你能展示方法 2 的实际代码吗?
-
处理器是什么?我有一种强烈的感觉,你可能会遇到类似的情况:Why is one loop so much slower than two loops?
-
u 和 v 现在是一样的。我认为你应该使用 v = new(buffer + sizeof(float)*num)
-
对方法 3 进行基准测试会很有趣:使用
std::vector -
什么是
num?它很大吗?大约 50k - 100k?
标签: c++ performance gcc compiler-optimization