我上了这门课
方法一:
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
}
方法二:
与方法 1 相同。除了在方法 2 中v
,u
, 和所有其他变量都分配在一个预先分配在堆上的大块上,使用 placement 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.
L1 缓存为 256K,Ram 为 8GB,页面大小为 4K。
编辑:更正了方法 2 中分配变量的错误。所有变量都正确分配在不同的部分。处理器是 Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz
编辑:在此处添加源 - Source。方法 1) 给出 69.58s,方法 2) 给出 46.74s。虽然不是快 2 倍,但它仍然很快。