我正在尝试学习如何使用内部函数。 所以,我的 C 代码是:
void Vor(
const int NbPoints,
const int height,
const int width,
float * X,
float * Y,
int * V,
int * const ouVor )
{
float Xd , Yd;
float Distance ,initDistance = FLT_MAX;
int Threshold;
int x , y; // pixel coordinates
int i;
for ( y = 0; y < height; y++ )
{
for ( x = 0; x < width; x++ )
{
for ( i = 0; i < NbPoints; i++ )
{
Xd = X[ i ] - x;
Yd = Y[ i ] - y;
Distance = Xd * Xd + Yd * Yd;
//if this Point is closer , assign proper threshold
if ( Distance < initDistance )
{
initDistance = Distance;
Threshold = V[ i ];
}
*( ouVor + ( x + y * width ) ) = Threshold;
} /* i */
} /* x */
} /* y */
}
现在,使用 openMP 和内在函数。我正在做:
void Vor(
const int NbOfPoints,
const int height,
const int width,
float * restrict X,
float * restrict Y,
int * restrict V,
int * restrict ouVor )
{
__m128 Xd , Yd;
__m128i Threshold;
int x , y; // pixel coordinates
float initDistance = FLT_MAX;
float * TempDistance = (float*) _mm_malloc( NbOfPoints * sizeof(*TempDistance) ,64 );
__m128 * SIMDTempDistance = (__m128*) TempDistance;
__m128 * theX = (__m128*) X;
__m128 * theY = (__m128*) Y;
__m128i * theV = (__m128i*) V;
__m128i * theVor = (__m128i*) ouVor;
#pragma omp parallel for default( none ) shared( X , Y , V , ouVor ,height , width ,NbOfPoints ) private ( x,y,Xd,Yd,TempDistance ,Threshold ) collapse(2)
for ( y = 0; y < height; y++ )
{
for ( x = 0; x < width; x++ )
{
__m128 Distance = _mm_load_ps( &initDistance );
for ( int i = 0; i < NbOfPoints; i++ )
{
Xd = _m128_sub_ps( theX[ i ] , x );
Yd = _m128_sub_ps( theY[ i ] , y );
SIMDTempDistance[ i ] = _m128_add_ps( Xd * Xd , Yd * Yd );
__m128 theMin = _m128_gmin_ps( SIMDTempDistance , &Distance );
Distance = theMin;
Threshold = theV[ i ];
} /* i */
//write result
*( ouVor + x + y * width ) = Threshold;
} /* x */
} /* y */
_mm_free( TempDistance );
}
我收到一些错误,例如:
function "_m128_sub_ps" declared implicitly
Xd = _m128_sub_ps( theX[ i ] , x );
error: a value of type "int" cannot be assigned to an entity of type "__m128"
Xd = _m128_sub_ps( theX[ i ] , x );
a value of type "__m128i" cannot be assigned to an entity of type "int"
*( ouVor + x + y * width ) = Threshold
(和 Yd 、theMin 、SIMDTempDistance 相同的错误)
我怎样才能克服这些问题?
此外,我删除了 if 语句并使用 _m128_gmin_ps 找到最小值。我的实现是否正确?
------------更新----------------
在 Sourav Ghosh 发表评论后,我搜索了标题。
我找不到 128 位的任何地方,所以我使用 256 位使用 #include <immintrin.h>
在更正几行之后:
__m256 Distance = _mm256_load_ps( &intiDistance );
__m256 theMin = _mm256_min_ps( SIMDTempDistance[ i ] , &Distance );
以及对 _mm256 而不是 _m256 的所有函数调用,我只收到这些错误:
error: argument of type "int" is incompatible with parameter of type "__m256"
Xd = _mm256_sub_ps( theX[ i ] , x );
Yd = _mm256_sub_ps( theY[ i ] , y );
x 和 y 是整数并在循环中使用。我不知道如何克服这个问题。
-----更新--------------------
我想!我正在类型转换.. 我用过:
__m256i xxIdx = _mm256_set1_epi32( x );
__m256 xIdx = _mm256_castsi256_ps( xxIdx );
现在,我的代码是:
void Vor(
const int NbOfPoints,
const int height,
const int width,
float * restrict X,
float * restrict Y,
int * restrict V,
int * restrict ouVor )
{
__m256 Xd , Yd;
__m256i Threshold;
int x , y; // pixel coordinates
float * TempDistance = (float*) _mm_malloc( NbOfPoints * sizeof(*TempDistance) ,64 );
__m256 * SIMDTempDistance = (__m256*) TempDistance;
__m256 * theX = (__m256*) X;
__m256 * theY = (__m256*) Y;
__m256i * theV = (__m256i*) V;
__m256i * theVor = (__m256i*) ouVor;
#pragma omp parallel for default( none ) shared( X , Y , V , ouVor ,height , width ,NbOfPoints ,ouVor ,theX,theY,theV ) private ( x,y,Xd,Yd,TempDistance ,Threshold,SIMDTempDistance ) collapse(2)
for ( y = 0; y < height; y++ )
{
for ( x = 0; x < width; x++ )
{
float initDistance = FLT_MAX;
__m256 Distance = _mm256_set1_ps( initDistance );
for ( int i = 0; i < NbOfPoints; i++ )
{
__m256i xxIdx = _mm256_set1_epi32( x );
__m256 xIdx = _mm256_castsi256_ps( xxIdx );
__m256i yyIdx = _mm256_set1_epi32( y );
__m256 yIdx = _mm256_castsi256_ps( yyIdx );
Xd = _m256_sub_ps( theX[ i ] , xIdx );
Yd = _m256_sub_ps( theY[ i ] , yIdx );
SIMDTempDistance[ i ] = _m256_add_ps( Xd * Xd , Yd * Yd );
__m256 theMin = _m256_gmin_ps( SIMDTempDistance , Distance );
Distance = theMin;
Threshold = theV[ i ];
} /* i */
//write result
*( ouVor + x + y * width ) = Threshold;
} /* x */
} /* y */
_mm_free( TempDistance );
}
我这样编译:
icc -std=c99 -g -openmp -qopt-report=2 -o mycode mycode.c
没关系。
但是运行代码会出现段错误..
在线:
Xd = _m256_sub_ps( theX[ i ] , xIdx );
Yd = _m256_sub_ps( theY[ i ] , yIdx );
最佳答案
我认为,您缺少一些包含 _m128_sub_ps()
函数前向声明的必需头文件。我们可以假设 _m128_sub_ps()
函数的返回类型为 __m128
,但如果没有适当的前向声明,编译器会假设默认 _m128_sub_ps()
函数的返回类型为 int
。这就是为什么编译器发出
function "_m128_sub_ps" declared implicitly
然后,int
返回值被分配给类型为 __m128
的变量,从而产生了问题。
编辑:
根据修改后的代码,
int x , y; // pixel coordinates
应该是
__m256 x , y; // pixel coordinates
作为signature of _mm256_sub_ps()
要求两个参数都是 __m256
关于c - 学习使用内在函数——使用 _mm256_sub_ps 的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29489783/