2014-10-14 1 views
0

Во время реализации курсовой работы я должен написать программу MPI для решения механики сплошных сред PDE. (FORTRAN)MPI коллективный выход 5 несмежных 3D-массивов в специальной форме

В файле программы последовательности записывается следующим образом:

do i=1,XX 
    do j=1,YY 
     do k=1,ZZ 
      write(ifile) R(i,j,k) 
      write(ifile) U(i,j,k) 
      write(ifile) V(i,j,k) 
      write(ifile) W(i,j,k) 
      write(ifile) P(i,j,k) 
     end do 
    end do 
end do 

В параллельной программе, я пишу то же самое, следующим образом: /распараллеливание происходит только вдоль оси Х/

call MPI_TYPE_CREATE_SUBARRAY(4, [INT(5), INT(ZZ),INT(YY), INT(XX)], [5,ZZ,YY,PDB(iam).Xelements], [0, 0, 0, PDB(iam).Xoffset], MPI_ORDER_FORTRAN, MPI_FLOAT, slice, ierr) 
call MPI_TYPE_COMMIT(slice, ierr) 

call MPI_FILE_OPEN(MPI_COMM_WORLD, cFileName, IOR(MPI_MODE_CREATE, MPI_MODE_WRONLY), MPI_INFO_NULL, ifile, ierr) 

do i = 1,PDB(iam).Xelements 
    do j = 1,YY 
     do k = 1,ZZ 
      dataTmp(1,k,j,i) = R(i,j,k) 
      dataTmp(2,k,j,i) = U(i,j,k) 
      dataTmp(3,k,j,i) = V(i,j,k) 
      dataTmp(4,k,j,i) = W(i,j,k) 
      dataTmp(5,k,j,i) = P(i,j,k) 
     end do 
    end do 
end do 

call MPI_FILE_SET_VIEW(ifile, offset, MPI_FLOAT, slice, 'native', MPI_INFO_NULL, ierr) 
call MPI_FILE_WRITE_ALL(ifile, dataTmp, 5*PDB(iam).Xelements*YY*ZZ, MPI_FLOAT, wstatus, ierr) 
call MPI_BARRIER(MPI_COMM_WORLD, ierr) 

Это хорошо работает. Но я не уверен в использовании массива dataTmp. Какое решение будет быстрее и правильнее? Как насчет использования 4D-массива, такого как dataTmp во всей программе? Или, может быть, я должен создать 5 специальных mpi_types с разными смещениями.

ответ

0

Если скорость ввода-вывода является проблемой, и у вас есть опция, я бы предложил изменить формат файла - или, альтернативно, как данные выложены в памяти - более тесно выстроены: в серийном коде , запись данные в этом транспонированном и чередовании пути будут очень медленно:

program testoutput 
implicit none 

integer, parameter :: XX=512, YY=512, ZZ=512 
real, dimension(:,:,:), allocatable :: R, U, V, W, P 
integer :: timer 
integer :: ifile 
real :: elapsed 
integer :: i,j,k 

allocate(R(XX,YY,ZZ), P(XX,YY,ZZ)) 
allocate(U(XX,YY,ZZ), V(XX,YY,ZZ), W(XX,YY,ZZ)) 

R = 1.; U = 2.; V = 3.; W = 4.; P = 5. 

open(newunit=ifile, file='interleaved.dat', form='unformatted', status='new') 
call tick(timer) 
do i=1,XX 
    do j=1,YY 
     do k=1,ZZ 
      write(ifile) R(i,j,k) 
      write(ifile) U(i,j,k) 
      write(ifile) V(i,j,k) 
      write(ifile) W(i,j,k) 
      write(ifile) P(i,j,k) 
     end do 
    end do 
end do 
elapsed=tock(timer) 
close(ifile) 

print *,'Elapsed time for interleaved: ', elapsed 

open(newunit=ifile, file='noninterleaved.dat', form='unformatted',status='new') 
call tick(timer) 
write(ifile) R 
write(ifile) U 
write(ifile) V 
write(ifile) W 
write(ifile) P 
elapsed=tock(timer) 
close(ifile) 

print *,'Elapsed time for noninterleaved: ', elapsed 

deallocate(R,U,V,W,P) 
contains 

subroutine tick(t) 
    integer, intent(OUT) :: t 

    call system_clock(t) 
end subroutine tick 

! returns time in seconds from now to time described by t 
real function tock(t) 
    integer, intent(in) :: t 
    integer :: now, clock_rate 

    call system_clock(now,clock_rate) 

    tock = real(now - t)/real(clock_rate) 
end function tock 

end program testoutput 

Бег дает

$ gfortran -Wall io-serial.f90 -o io-serial 
$ ./io-serial 
Elapsed time for interleaved: 225.755005  
Elapsed time for noninterleaved: 4.01700020 

как Rob Латы, который знает больше, чем несколько вещей об этой вещи, говорит, ваш транспозиция для параллельной версии в порядке - это чередование и перемещение петь явно в памяти, где он намного быстрее, а затем взрывает его на диск. Это примерно так же быстро, как и IO.

Вы можете определенно избежать массива dataTmp, написав один или пять отдельных типов данных, чтобы сделать транспонирование/перемежение для вас на выходе на диск с помощью процедуры MPI_File_write_all. Это даст вам немного больше баланса между использованием памяти и производительностью. Вы не будете явно определять большой трехмерный массив, но код MPI-IO улучшит производительность по сравнению с отдельными элементами, выполнив справедливую бит буферизации, что означает, что определенный объем памяти выделяется для выполнения писать эффективно. Хорошей новостью является то, что баланс будет настраиваться, установив подсказки MPI-IO в переменной Info; плохая новость заключается в том, что код, вероятно, будет менее ясным, чем то, что у вас есть сейчас.

+0

Благодарим вас за ответ. Но, к сожалению, я не могу изменить формат файла. Я отчетливо понимаю, что этот формат неудобен, но я не могу. Я новичок в MPI. Не могли бы вы показать какой-нибудь удобный пример того, что вы описали (отдельные типы данных и т. Д.) – Vasiliy

+0

Когда я отправил свой ответ, мне было интересно, почему @ Джонатан Дурси еще не дал ответа. Очевидно, он прилагал немало усилий, чтобы сохранить титул короля StackOverflow. –

+0

@ Vasiliy, возможно, вы можете рассмотреть предварительную обработку и пост-обработку, чтобы получить файл в формате, который вы хотите для производительности? часто шаг преобразования может произойти быстро, хотя для достаточно больших наборов данных, конечно, есть точка, где последовательное пре-или пост-преобразование несостоятельно. –

1

Использование dataTmp в порядке, если у вас есть память. ваш MPI_FILE_WRITE_ALL вызов будет самой дорогой частью этого кода.

Вы сделали сложную часть, установив представление файла MPI-IO. если вы хотите избавиться от dataTmp, вы можете создать тип данных MPI для описания массивов (возможно, используя MPI_Type_hindexed и MPI_Get_address)), а затем используйте MPI_BOTTOM в качестве буфера памяти.

+0

Благодарим за ответ! Является ли способ избавиться от dataTmp быстрее (или равной скорости), чем способ использования этого массива? Если это медленнее, мне это не подходит. Если вы не возражаете, пожалуйста, посмотрите мой еще один вопрос о MPI-IO файла little-endian в системах с большими концами. – Vasiliy

 Смежные вопросы

  • Нет связанных вопросов^_^