如果我有這段代碼,
subroutine min_distance(r,n,k,centroid,distance,indices,distancereg)
integer, intent(out):: n,k
real,dimension(:,:),intent(in),allocatable::centroid
real,dimension(:,:),intent(in),allocatable::r
integer,dimension(:),intent(out),allocatable::indices,distancereg
real ::d_min
integer::y,i_min,j,i
integer,parameter :: data_dim=2
allocate (indices(n))
allocate (distancereg(k))
!cost=0.d0
do j=1,n
i_min = -1
d_min=1.d6
do i=1,k
distance=0.d0
distancereg(i)=0.d0
do y=1,data_dim
distance = distance abs(r(y,j)-centroid(y,i))
distancereg(i)=distancereg(i) abs(r(y,j)-centroid(y,i))
end do
if (distance<d_min) then
d_min=distance
i_min=i
end if
end do
if( i_min < 0 ) print*," found error by assigning k-index to particle ",j
indices(j)=i_min
end do
我想要做的是,當我計算每個 k 的距離時,我想將它并行化。IE。分配每個執行緒去做。例如,如果 k=3,則對于 k=1,執行緒 1 計算的距離,依此類推。我已經嘗試使用 omp_nested、omp_ordered,但仍然顯示一些錯誤。如果有任何建議/指導,將不勝感激。
謝謝
uj5u.com熱心網友回復:
如果你想并行化一個回圈(或回圈嵌套),你必須首先想知道哪些迭代是獨立的。在您的情況下,每次外部j迭代計算的i_min值是 1. 在每次i迭代中初始化,并且 2. 寫入 location (j)。所以每個i_min計算都是獨立的,你可以使j回圈并行。(你也有d_min,但從未使用過。)
如果j回圈足夠長,應該足以獲得高性能。您可能想查看下一個回圈i。distance它為每次迭代計算一個單獨的值,因此這又是并行的。除了你 update i_min,d_min,所以你需要宣告那個回圈 a reduction。
但是,這兩個回圈并不是“完美嵌套”的,因此您不能將總i,j迭代空間分布在執行緒上。
TLDR:您的外j回圈可以并行化。
uj5u.com熱心網友回復:
簡單地說:
do j=1,n
distancereg(:)=0.d0
!$OMP PARALLEL DO PRIVATE(y)
do i=1,k
do y=1,data_dim
distancereg(i)=distancereg(i) abs(r(y,j)-centroid(y,i))
end do
end do
!$OMP PARALLEL END DO
indices(j)=minloc(distancereg,dim=1)
end do
由于您正在存盤每個的距離i,因此可以在回圈之后推遲對最小值的搜索i
或者并行化外回圈(這里你不需要存盤距離):
!$OMP PARALLEL DO PRIVATE(i,y,i_min,d_min,distance)
do j=1,n
i_min = -1
d_min=1.d6
do i=1,k
distance=0.d0
do y=1,data_dim
distance = distance abs(r(y,j)-centroid(y,i))
end do
if (distance<d_min) then
d_min=distance
i_min=i
end if
end do
if( i_min < 0 ) print*," found error by assigning k-index to particle ",j
indices(j)=i_min
end do
!$OMP END PARALLEL DO
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/534257.html
標籤:循环并行处理打开mp做
