Mac OSX 上的向量标量乘法 AVX 分段错误
Vector Scalar multiplication AVX segmentation fault on Mac OSX
您好,我正在尝试在 Sandy Bridge 处理器 i7-3720QM (~2012)
上使用 AVX
编写矢量标量乘法代码。
该代码是在 Mac OSX 10.8
.
上使用 GNU gcc
编译的 C
代码
gcc -mavx -Wa,-q -o bb5 code1.c -lm
我得到 Segmentation fault: 11
。请帮忙。
输出:
3.000000 6.000000 9.000000 12.000000
Segmentation fault: 11
那么,store
命令似乎没有正常工作?谢谢。最后我想做类似的事情
A = A + x*B
其中 x
是标量,A
和 B
是矢量。函数 void matsca(const double* a, double c, double *b)
将被一次又一次地调用以对步幅为 8
的大尺寸 double
向量进行操作,因为 AVX
可以采用 4
双元素 (256 bits)
。感谢您的帮助。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <immintrin.h>
void matsca(const double* a, double c, double *b)
{
__m256d a0 = _mm256_loadu_pd(a+0);
__m256d a1 = _mm256_set1_pd(c);
__m256d a2 = _mm256_mul_pd(a0,a1);
double* f = (double*)&a2;
printf("%f %f %f %f \n",f[0],f[1],f[2],f[3]);
_mm256_store_pd(b,a2);
}
int main()
{
double m1[11]={1,2,3,4,5,6,7,8,9,10,11};
double *m3;
double m2=3;
int i;
matsca(&m1[0],m2,&m3[0]);
for (i=0; i<3; i=i+1)
{
printf("%d %f \n",i,m3[i]);
}
return 0;
}
这是您原来的 matsca
的 fixed/improved 版本:
inline void matsca(const double *a, const double c, double *b)
{
__m256d a0 = _mm256_loadu_pd(a);
__m256d a1 = _mm256_set1_pd(c);
__m256d a2 = _mm256_mul_pd(a0, a1);
#if DEBUG > 0
double *f = (double *)&a2;
printf("%f %f %f %f\n", f[0], f[1], f[2], f[3]);
#endif
_mm256_storeu_pd(b, a2);
}
然而,您可能需要考虑使其更通用,以便它可以处理任何大小的向量,例如
inline void matsca(const double *a, const double c, double *b, const size_t n)
{
const __m256d a1 = _mm256_set1_pd(c);
size_t i;
for (i = 0; i + 4 <= n; i += 4)
{
__m256d a0 = _mm256_loadu_pd(&a[i]);
__m256d a2 = _mm256_mul_pd(a0, a1);
_mm256_storeu_pd(b, &a2[i]);
}
for ( ; i < n; ++i) // handle any odd elements at end of vector
{
a2[i] = a1[i] * a2;
}
}
这样你就可以分摊函数调用、初始化常量向量等的成本
您好,我正在尝试在 Sandy Bridge 处理器 i7-3720QM (~2012)
上使用 AVX
编写矢量标量乘法代码。
该代码是在 Mac OSX 10.8
.
GNU gcc
编译的 C
代码
gcc -mavx -Wa,-q -o bb5 code1.c -lm
我得到 Segmentation fault: 11
。请帮忙。
输出:
3.000000 6.000000 9.000000 12.000000
Segmentation fault: 11
那么,store
命令似乎没有正常工作?谢谢。最后我想做类似的事情
A = A + x*B
其中 x
是标量,A
和 B
是矢量。函数 void matsca(const double* a, double c, double *b)
将被一次又一次地调用以对步幅为 8
的大尺寸 double
向量进行操作,因为 AVX
可以采用 4
双元素 (256 bits)
。感谢您的帮助。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <immintrin.h>
void matsca(const double* a, double c, double *b)
{
__m256d a0 = _mm256_loadu_pd(a+0);
__m256d a1 = _mm256_set1_pd(c);
__m256d a2 = _mm256_mul_pd(a0,a1);
double* f = (double*)&a2;
printf("%f %f %f %f \n",f[0],f[1],f[2],f[3]);
_mm256_store_pd(b,a2);
}
int main()
{
double m1[11]={1,2,3,4,5,6,7,8,9,10,11};
double *m3;
double m2=3;
int i;
matsca(&m1[0],m2,&m3[0]);
for (i=0; i<3; i=i+1)
{
printf("%d %f \n",i,m3[i]);
}
return 0;
}
这是您原来的 matsca
的 fixed/improved 版本:
inline void matsca(const double *a, const double c, double *b)
{
__m256d a0 = _mm256_loadu_pd(a);
__m256d a1 = _mm256_set1_pd(c);
__m256d a2 = _mm256_mul_pd(a0, a1);
#if DEBUG > 0
double *f = (double *)&a2;
printf("%f %f %f %f\n", f[0], f[1], f[2], f[3]);
#endif
_mm256_storeu_pd(b, a2);
}
然而,您可能需要考虑使其更通用,以便它可以处理任何大小的向量,例如
inline void matsca(const double *a, const double c, double *b, const size_t n)
{
const __m256d a1 = _mm256_set1_pd(c);
size_t i;
for (i = 0; i + 4 <= n; i += 4)
{
__m256d a0 = _mm256_loadu_pd(&a[i]);
__m256d a2 = _mm256_mul_pd(a0, a1);
_mm256_storeu_pd(b, &a2[i]);
}
for ( ; i < n; ++i) // handle any odd elements at end of vector
{
a2[i] = a1[i] * a2;
}
}
这样你就可以分摊函数调用、初始化常量向量等的成本