如何防止使用 arm-none-eabi-gcc 编译器对该函数进行向量运算优化?
How to prevent vector operation optimization over this function with arm-none-eabi-gcc compiler?
我的代码
我正在使用一个在学术项目中使用此函数的简单代码:
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;
}
}
}
我的目标架构
我的代码应该只对 'data' 执行这个简单的矩阵运算,并用结果填充 'distance' 矩阵。然而,在我的学术项目中,我对编译器如何为我正在使用的 ARM 架构优化这些向量操作感兴趣。编译的命令行包含以下内容:
arm-none-eabi-gcc <flags> <my_sources> -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard <more_flags>
我的程序旨在 运行 在嵌入式 Xilinx Zynq-7000 设备中,其架构包括用于矢量运算的 NEON 优化指令集(在 this nice presentation 中描述)
我的问题
我必须在使用和不使用编译器优化的情况下跟踪 '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}
我找不到编译此代码的方法,因此未使用这些优化指令。
您知道可以避免这些指令的任何编译配置或代码技巧吗?感谢对此问题的任何帮助。
您引用的指令不是矢量运算:
vsub.f32 s15, s13, s15
这是一个简单的 32 位浮点减法。您可以通过使用32位形式的S寄存器和指令中的.f32
后缀来判断
我重新审视了这个问题,发现我的环境设置为在调试模式下构建,因此没有真正进行优化。
实际优化后的代码使用了VLDM和VSTM指令。但是,当我添加 pragma
时,它们不会生成
#pragma GCC optimize ("O0")
在我的源文件中。
我的代码
我正在使用一个在学术项目中使用此函数的简单代码:
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;
}
}
}
我的目标架构
我的代码应该只对 'data' 执行这个简单的矩阵运算,并用结果填充 'distance' 矩阵。然而,在我的学术项目中,我对编译器如何为我正在使用的 ARM 架构优化这些向量操作感兴趣。编译的命令行包含以下内容:
arm-none-eabi-gcc <flags> <my_sources> -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard <more_flags>
我的程序旨在 运行 在嵌入式 Xilinx Zynq-7000 设备中,其架构包括用于矢量运算的 NEON 优化指令集(在 this nice presentation 中描述)
我的问题
我必须在使用和不使用编译器优化的情况下跟踪 '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}
我找不到编译此代码的方法,因此未使用这些优化指令。
您知道可以避免这些指令的任何编译配置或代码技巧吗?感谢对此问题的任何帮助。
您引用的指令不是矢量运算:
vsub.f32 s15, s13, s15
这是一个简单的 32 位浮点减法。您可以通过使用32位形式的S寄存器和指令中的.f32
后缀来判断
我重新审视了这个问题,发现我的环境设置为在调试模式下构建,因此没有真正进行优化。
实际优化后的代码使用了VLDM和VSTM指令。但是,当我添加 pragma
时,它们不会生成#pragma GCC optimize ("O0")
在我的源文件中。