亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么在這個openmp代碼中發生了分段錯誤?

為什么在這個openmp代碼中發生了分段錯誤?

慕斯王 2019-07-27 10:29:49
為什么在這個openmp代碼中發生了分段錯誤?主程序:program main                                                                                                                                                      use omp_lib                                                                                                                                                     use my_module                                                                                                                                                   implicit none                                                                                                                                                   integer, parameter :: nmax = 202000                                                                                                                             real(8) :: e_in(nmax) = 0.D0                                                                                                                                    integer i         do i=1,2                                                                                                                                                           print *, e_in(i)                                                                                                                                                print *, eTDSE(i)                                                                                                                                            end do編譯使用:ifort -openmp main.f90 my_module.f90它在執行時給出Segmentation故障。如果刪除主程序中的一個打印命令,它運行正常。另外如果刪除omp函數并在沒有-openmp選項的情況下編譯,它也運行正常。
查看完整描述

2 回答

?
慕姐4208626

TA貢獻1852條經驗 獲得超7個贊

導致此行為的最可能原因是您的堆棧大小限制太?。o論出于何種原因)。由于e_in每個OpenMP線程都是私有的,因此每個線程在線程堆棧上分配一個副本(即使您已指定-heap-arrays!)。取1616 kB(或1579 KiB)的202000元素REAL(KIND=8)

堆棧大小限制可以通過以下幾種機制控制:

  • 在標準的Unix系統shell上,堆棧大小的數量由ulimit -s <stacksize in KiB>。這也是主OpenMP線程的堆棧大小限制。pthreads在創建新線程時,POSIX threads()庫也將此限制的值用作默認線程堆棧大小。

  • OpenMP支持通過環境變量控制所有其他線程的堆棧大小限制OMP_STACKSIZE。它的值是一個帶有可選后綴kK用于KiB,mMf為MiB或gG用于GiB的數字。此值不會影響主線程的堆棧大小。

  • GNU OpenMP運行時(libgomp)識別非標準環境變量GOMP_STACKSIZE。如果設置它會覆蓋值OMP_STACKSIZE

  • 英特爾OpenMP運行時可識別非標準環境變量KMP_STACKSIZE。如果設置它會覆蓋值的值,OMP_STACKSIZE并且還會覆蓋使用GOMP_STACKSIZE兼容性OpenMP運行時的值(這是默認值,因為當前唯一可用的英特爾OpenMP運行時庫是compat一個)。

  • 如果*_STACKSIZE未設置任何變量,則英特爾OpenMP運行時的默認值為2m32位體系結構和4m64 位體系結構。

  • 在Windows上,主線程的堆棧大小是PE頭的一部分,并由鏈接器嵌入到那里。如果使用Microsoft LINK進行鏈接,則使用/STACK:reserve[,commit]。該reserve參數指定以字節為單位的最大堆棧大小而可選commit參數指定初始提交大小。兩者都可以使用0x前綴指定為十六進制值。如果不能重新鏈接可執行文件,則可以通過編輯PE頭來修改堆棧大小EDITBIN。它采用與鏈接器相同的堆棧相關參數。使用MSVC的整個程序優化enabled(/GL)編譯的程序無法編輯。

  • Win32目標的GNU鏈接器支持通過--stack參數設置堆棧大小。要直接從GCC傳遞選項,-Wl,--stack,<size in bytes>可以使用。

請注意,線程堆棧實際上是使用由(或默認值)設置的大小分配*_STACKSIZE,與主線程的堆棧不同,主線程從較小的堆棧開始,然后根據需求增長到設置的限制。因此,不要設置*_STACKSIZE為任意大的值,否則可能會達到進程虛擬內存大小限制。

這里有些例子:

$ ifort -openmp my_module.f90 main.f90

將主堆棧大小限制設置為1 MiB(額外的OpenMP線程將默認獲得4 MiB):

$ ulimit -s 1024$ ./a.outzsh: segmentation fault (core dumped)  ./a.out

將主堆棧大小限制設置為1700 KiB:

$ ulimit -s 1700$ ./a.out
  0.000000000000000E+000
 (0.000000000000000E+000,0.000000000000000E+000)
  0.000000000000000E+000
 (0.000000000000000E+000,0.000000000000000E+000)

將主堆棧大小限制設置為2 MiB,將附加線程的堆棧大小設置為1 MiB:

$ ulimit -s 2048$ KMP_STACKSIZE=1m ./a.outzsh: segmentation fault (core dumped)  KMP_STACKSIZE=1m ./a.out

在大多數Unix系統上,主線程的堆棧大小限制由PAM或其他登錄機制設置(請參閱參考資料/etc/security/limits.conf)。Scientific Linux 6.3的默認值為10 MiB。

另一種可能導致錯誤的可能情況是虛擬地址空間限制設置得太低。例如,如果虛擬地址空間限制為1 GiB且線程堆棧大小限制設置為512 MiB,則OpenMP運行時將嘗試為每個其他線程分配512 MiB。使用兩個線程,只有堆棧的1 GiB,當代碼,共享庫,堆等的空間相加時,虛擬內存大小將超過1 GiB,并且會發生錯誤:

將虛擬地址空間限制設置為1 GiB,并使用另外兩個具有512 MiB堆棧的線程運行(我已將注釋注釋掉omp_set_num_threads()):

$ ulimit -v 1048576$ KMP_STACKSIZE=512m OMP_NUM_THREADS=3 ./a.outOMP: Error #34: System unable to allocate necessary resources for OMP thread:OMP: System error #11: Resource temporarily unavailableOMP: Hint: Try decreasing the value of OMP_NUM_THREADS.forrtl: error (76): Abort trap signal... trace omitted ...zsh: abort (core dumped)  OMP_NUM_THREADS=3 KMP_STACKSIZE=512m ./a.out

在這種情況下,OpenMP運行時庫將無法創建新線程,并在中止程序終止之前通知您。


查看完整回答
反對 回復 2019-07-27
?
米脂

TA貢獻1836條經驗 獲得超3個贊

分段錯誤是由于使用OpenMP時的堆棧內存限制。使用上一個答案中的解決方案并沒有解決我在Windows操作系統上的問題。使用內存分配到堆而不是堆棧內存似乎工作:

integer, parameter :: nmax = 202000  real(dp), dimension(:), allocatable :: e_ininteger iallocate(e_in(nmax))e_in = 0! rest of codedeallocate(e_in)

此外,這不涉及更改任何默認環境參數。

在此確認并參考ohm314的解決方案:使用堆內存分配的大型陣列


查看完整回答
反對 回復 2019-07-27
  • 2 回答
  • 0 關注
  • 2126 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號