【发布时间】:2016-08-18 18:36:13
【问题描述】:
double compute_inner_contraction_0( double* X, double* T, int n, int f, int m, int e, int No, int Nv )
{
double contraction_value = 0.0;
int l_begin = 0;
int l_end = m;
for ( int l = l_begin; l < l_end; l++ )
{
int k_begin = 0;
int k_end = l;
for ( int k = k_begin; k < k_end; k++ )
{
contraction_value += (-1)*X[n * Nv * No * No * No * No + e * No * No * No * No + m * No * No * No + l * No * No + l * No + k]*T[k * Nv + f];
}
}
return contraction_value;
}
void compute_contraction_0( double* X, double* T, int No, int Nv, double* ExEx_block , int nthd )
{
omp_set_dynamic(0);
omp_set_num_threads(nthd);
#pragma omp parallel for
for ( int n = 0; n < No; n++ )
{
int f_begin = 0;
int f_end = Nv;
for ( int f = f_begin; f < f_end; f++ )
{
int m_begin = 0;
int m_end = n;
for ( int m = m_begin; m < m_end; m++ )
{
int e_begin = 0;
int e_end = f;
for ( int e = e_begin; e < e_end; e++ )
{
ExEx_block[n * Nv * No * Nv + f * No * Nv + m * Nv + e] += compute_inner_contraction_0( X, T, n, f, m, e, No, Nv);
}
}
}
}
}
大家好,很抱歉功能太长了。请不要担心内存泄漏的索引,因为它们已经过广泛测试。基本上它在数组 X 和 T 中取数字,然后将它们相乘,然后将结果添加到另一个数组 ExEx_block。此代码将在多线程上运行,但与在一个线程上运行的结果相比,会给出非常错误的计算结果(这是正确的)。能否请你帮忙?它被构建为一个共享库(具有许多其他类似的功能)并从 Python 包装器加载。操作系统是 CentOS 6,编译器是 gcc-4.4.7 这是一个四核 Xeon E5-4620 (Sandy-EP)(总共 32 个内核)服务器,具有 480 GB 的 DDR3。不,Nv 只是计算中需要的整数。 nthd(线程数)通常只有 10 或 20。这些数组的大小可以达到 17 GB。非常感谢您的宝贵时间。
【问题讨论】:
-
当您说“关闭结果”时,您的意思是不正确/不匹配的结果,还是只是执行时间不是您所希望的?您的平台是什么(例如 RAM 的数量和 RAM 总线的速度、cpu 频率、内核数量、缓存大小等)?而且,数组大小和
nthd值是多少?No?您是否尝试过调用 python 之外的函数的测试程序?我会编辑您的问题并添加此信息。 -
我的意思是它在多线程上给出了非常错误的结果。从未在 python 之外测试过,将尝试在 C 中加载它。
-
尝试在
ExEx_block[n * Nv * No * Nv + f * No * Nv + m * Nv + e] += compute_inner_contraction_0( X, T, n, f, m, e, No, Nv);之前添加#pragma omp critical。可能是多个线程正在尝试读取和写入同一个内存位置(我无法按照您的代码...) -
谢谢你们。抱歉,它们是批量生成的……今天下午试试。再次感谢。
-
你能添加一个最小的测试用例吗?你怎么称呼compute_contraction_0?