我正在为双 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 秒)。
您对加快计算速度有什么建议吗?