我正在努力并行化已经执行循环和调用子例程的代码的一小部分。但是结果与1个线程或2个线程不一致。
对于这种类型的程序,我们必须使用锁吗?
return sao.sessionmaker(bind=engine, autoflush=False)()
任何人都可以提供一些线索吗?
答案 0 :(得分:2)
我不确定代码的其余部分是否正确(我实际上甚至没有尝试将其读取为TBH),但开头显然是错误的:
!$OMP parallel private(kk,j,i,k1,j1,i1,k2,j2,i2,ic,icm,xx,yy,ydatm),shared(undef,lt,ln,nd,xd,tgrd,ndaym)
thread_id = OMP_GET_THREAD_NUM()
num_threads = OMP_GET_NUM_THREADS()
if(thread_id.eq.0) thread_id=thread_id+1
start_no = (thread_id * ndaym / num_threads);
end_no = ((thread_id + 1) * ndaym / num_threads);
我会尝试总结一下我在这个片段中发现的错误:
thread_id
,num_threads
,start_no
和end_no
未声明为private
。因此它们隐含shared
,这显然是非常错误的。为了避免这种基本陷阱,我强烈建议您在default(none)
指令中使用!$omp parallel
子句。这绝对会给你带来很多麻烦。if(thread_id.eq.0) thread_id=thread_id+1
:好的,假设thread_id
已经(应该有)声明private
。在那之后,2个不同的线程(线程#0和#1)将具有thread_id
的相同值,即1.这有什么意义呢?start_no
值计算end_no
和private
(甚至一次声明为thread_id
),这对于线程#0来说是假的。首先尝试修复它们并查看它给出的内容。
对代码的其余部分进行额外一瞥使我怀疑deallocate(xx,yy)
可能也是一个问题:除非分配是在并行区域完成的(看起来并非如此)在这里,但仍然是可能的),解除分配应该移到它之外。