我正在针对双核Cortex-A9处理器优化两个一维数组的逐元素乘法。开发板上运行Linux,并且我正在使用GCC 4.5.2编译器。
以下是我的C++内联汇编函数。src1、src2和dst都是16字节对齐的。
更新:可测试代码:
void Multiply(
const float* __restrict__ src1,
const float* __restrict__ src2,
float* __restrict__ dst,
const unsigned int width,
const unsigned int height)
{
int loopBound = (width * height) / 4;
asm volatile(
".loop: \n\t"
"vld1.32 {q1}, [%[src1]:128]! \n\t"
"vld1.32 {q2}, [%[src2]:128]! \n\t"
"vmul.f32 q0, q1, q2 \n\t"
"vst1.32 {q0}, [%[dst]:128]! \n\t"
"subs %[lBound], %[lBound], $1 \n\t"
"bge .loop \n\t"
:
:[dst] "r" (dst), [src1] "r" (src1), [src2] "r" (src2),
[lBound] "r" (loopBound)
:"memory", "d0", "d1", "d2", "d3", "d4", "d5
);
}
//The following function describes how to test the element wise multiplication
void Test()
{
const unsigned int width = 1024, height = 1024;
float* src1 __attribute__((aligned(16))) = new float[width * height];
float* src2 __attribute__((aligned(16))) = new float[width * height];
float* dst __attribute__((aligned(16))) = new float[width * height];
for(unsigned int i = 0; i < (width * height); i++)
{
src1[i] = (float)rand();
src2[i] = (float)rand();
}
Multiply(src1, src2, dst, width, height);
std::cout << dst[0] << std::endl;
}
计算1024*1024个数值需要约0.016秒的时间。(两个线程:每个线程计算数组的一半)粗略解释,一个迭代的计算需要122个周期。这似乎有点慢。但瓶颈在哪里呢?
我甚至尝试了使用“pld”命令预加载L2缓存中的元素,“展开”循环以每次计算多达20个值,并重新排列指令以确保处理器不等待内存。但我没有得到太大的加速(最多快了0.001秒)。
你有什么建议可以加速计算吗?