0

我的代码

我正在使用一个在学术项目中使用此功能的简单代码:

void calculateDistanceMatrix(const float data[M][N],
                             float distance[M][N]) {
    float sum = 0.0;
    for(int i = 0; i < M; i++) {
        for(int j = i+1; j < M; j++) {
            for(int k = 0; k < N; w++) {
                sum += (data[i][k] - data[j][k]) *
                       (data[i][k] - data[j][k]);
            }
            distance[i][j] = sum;
            distance[j][i] = sum;
            distance[i][i] = 0.0;
            sum = 0.0;
        }
    }
}

我的目标架构

我的代码应该只对“数据”执行这个简单的矩阵运算,并用结果填充“距离”矩阵。然而,在我的学术项目中,我感兴趣的是编译器如何针对我正在使用的 ARM 架构优化这些向量操作。编译的命令行包含以下内容:

arm-none-eabi-gcc <flags> <my_sources> -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard <more_flags>

我的程序旨在在嵌入式 Xilinx Zynq-7000 设备中运行,其架构包括针对向量操作的 NEON 优化指令集(在这个不错的演示文稿中进行了描述)

我的问题

我必须在有和没有编译器优化的情况下跟踪“calculateDistanceMatrix”函数中向量操作的执行性能。我注意到汇编输出包括用于向量加载和存储操作的共享 NEON 和 VFP 指令(在ARM's Assembler Reference for Version 5.0中有详细说明):

ecf37a01    vldmia  r3!, {s15}
ecf26a01    vldmia  r2!, {s13}
e1530000    cmp r3, r0
ee777ae6    vsub.f32    s15, s15, s13
ee077aa7    vmla.f32    s14, s15, s15
1afffff9    bne 68 <calculateDistanceMatrix+0x48>
eca17a01    vstmia  r1!, {s14}

我找不到编译此代码的方法,以便使用这些优化的指令。

你知道任何可以避免这些指令的编译配置或代码技巧吗?感谢有关此问题的任何帮助。

4

2 回答 2

1

您引用的指令不是向量运算: vsub.f32 s15, s13, s15 这是一个简单的 32 位浮点减法。您可以通过使用 32 位形式的 S 寄存器和.f32指令中的后缀来判断

于 2018-07-10T22:06:00.973 回答
1

我重新审视了这个问题,发现我的环境设置为在调试模式下构建,因此没有真正进行优化。

实际优化的代码使用 VLDM 和 VSTM 指令。但是,当我添加编译指示时,它们不会生成

#pragma GCC optimize ("O0")

在我的源文件中。

于 2018-10-05T22:16:07.887 回答