我已经实现了两个不同的函数来将double数字舍入为整数。
这是第一个功能
static inline int round_v1(double value)
{
int t;
__asm
{
fld value;
fistp t;
}
return t;
}
这是第二个功能
static inline int round_v2(double value)
{
double intpart, fractpart;
fractpart = modf(value, &intpart);
if ((fabs(fractpart) != 0.5) || ((((int)intpart) % 2) != 0))
return (int)(value + (value >= 0 ? 0.5 : -0.5));
else
return (int)intpart;
}
这两个函数在单线程中都可以正常工作,但第二个函数不能在多线程中工作(使用openMP)。当我使用第二个程序时,程序崩溃了。
以下是调用round_v1
或round_v2
函数的主要代码。
void
BilateralFilter_Invoker::doFilter() const
{
if (!src || !dst) return;
int i, j;
int src_width = width + (radius << 1);
omp_set_num_threads(2);
#pragma omp parallel for
for (i = 0; i < height; ++i)
{
unsigned char* pSrc = src + (i+radius)*src_step + radius;
unsigned char* pDst = dst + i*dst_step;
for (j = 0; j < width; ++j)
{
float sum = 0.f, wsum = 0.f;
int val0 = pSrc[j];
for (int k = 0; k < maxk; ++k)
{
int val = pSrc[j + space_offset[k]];
float w = space_weight[k] * color_weight[std::abs(val-val0)];
sum += val * w;
wsum += w;
}
//pDst[j] = (unsigned char)round_v2(sum / wsum);
pDst[j] = (unsigned char)round_v1(sum / wsum);
}
}
}
变量src
,dst
,height
,width
,src_step
,dst_step
,radius
,{{1 },maxk
,space_offset
,space_weight
是BilateralFilter_Invoker类的成员变量。
我只在调用color_weight
时分别调用round_v1
和round_v2
进行测试和程序崩溃。我想知道round_v2
函数是否会导致这个问题。为了进一步测试,我评论这一行
modf(double, double*)
并将其替换为
fractpart = modf(value, &intpart);
我再次运行程序,它没有再次崩溃。我不知道fractpart = intpart = value;
是否会导致此问题。或者我的代码中可能存在错误导致问题而不是modf(double, double*)
函数。
请注意,我使用的操作系统是Windows7,编译器是VC10。
答案 0 :(得分:4)
你在SO上使用OpenMP犯了最常见的错误。你需要将内循环的迭代器设为私有。你可以做到
#pragma omp parallel for private(j)
或使用循环初始声明
for (int j = 0; j < width; ++j)
事实上,由于你从不在它们适用的循环之外使用i
或j
,所以没有理由在循环之外声明它们C89样式。