aarch64-gcc simd 内联 asm,结果始终为 0
aarch64-gcc simd inline asm, result always 0
我尝试使用内联汇编程序进行 SIMD 乘法运算。但是,结果始终为零或(在其他情况下)变得无法理解(对我而言)值。
#include <stdio.h>
int main(void)
{
double x[2] = {2.0, 3.0};
double y[2] = {0.0, 0.0};
asm volatile (
"fmul %[y].2d, %[x].2d, %[x].2d\n"
: /* outputs */
[y] "=&w" (y)
: /* inputs */
[x] "w" (x)
: /* clobbers */
"cc"
);
printf("result = (%f, %f)\n",
y[0], y[1]);
return 0;
}
编译为
aarch64-linux-gnu-gcc -mcpu=cortex-a73 -march='armv8-a'
我总能得到输出
result = (0.000000, 0.000000)
但我希望 (4.0, 9.0)。请帮忙!
正如 Jester 所说,您必须将 value 传递给 asm
语句,而不是指向相关数据的指针。此值的正确类型是 arm_neon.h
中的 float64x2_t
。所以进行如下操作:
#include <stdio.h>
#include <arm_neon.h>
int main(void)
{
double x[2] = {2.0, 3.0};
double y[2] = {0.0, 0.0};
asm volatile (
"fmul %[y].2d, %[x].2d, %[x].2d\n"
: /* outputs */
[y] "=&w" (*(float64x2_t *)y)
: /* inputs */
[x] "w" (*(float64x2_t *)x)
: /* clobbers */
"cc"
);
printf("result = (%f, %f)\n",
y[0], y[1]);
return 0;
}
请注意,当您包含内部函数 header 时,您还不如直接使用内部函数:
int bar(void)
{
double x[2] = {2.0, 3.0};
double y[2] = {0.0, 0.0};
float64x2_t *xx = x, *yy = y;
*yy = vmulq_f64(*xx, *xx);
printf("result = (%f, %f)\n",
y[0], y[1]);
return 0;
}
我尝试使用内联汇编程序进行 SIMD 乘法运算。但是,结果始终为零或(在其他情况下)变得无法理解(对我而言)值。
#include <stdio.h>
int main(void)
{
double x[2] = {2.0, 3.0};
double y[2] = {0.0, 0.0};
asm volatile (
"fmul %[y].2d, %[x].2d, %[x].2d\n"
: /* outputs */
[y] "=&w" (y)
: /* inputs */
[x] "w" (x)
: /* clobbers */
"cc"
);
printf("result = (%f, %f)\n",
y[0], y[1]);
return 0;
}
编译为
aarch64-linux-gnu-gcc -mcpu=cortex-a73 -march='armv8-a'
我总能得到输出
result = (0.000000, 0.000000)
但我希望 (4.0, 9.0)。请帮忙!
正如 Jester 所说,您必须将 value 传递给 asm
语句,而不是指向相关数据的指针。此值的正确类型是 arm_neon.h
中的 float64x2_t
。所以进行如下操作:
#include <stdio.h>
#include <arm_neon.h>
int main(void)
{
double x[2] = {2.0, 3.0};
double y[2] = {0.0, 0.0};
asm volatile (
"fmul %[y].2d, %[x].2d, %[x].2d\n"
: /* outputs */
[y] "=&w" (*(float64x2_t *)y)
: /* inputs */
[x] "w" (*(float64x2_t *)x)
: /* clobbers */
"cc"
);
printf("result = (%f, %f)\n",
y[0], y[1]);
return 0;
}
请注意,当您包含内部函数 header 时,您还不如直接使用内部函数:
int bar(void)
{
double x[2] = {2.0, 3.0};
double y[2] = {0.0, 0.0};
float64x2_t *xx = x, *yy = y;
*yy = vmulq_f64(*xx, *xx);
printf("result = (%f, %f)\n",
y[0], y[1]);
return 0;
}