2 回答
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。它的值是一個帶有可選后綴k/K用于KiB,m/Mf為MiB或g/G用于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運行時庫將無法創建新線程,并在中止程序終止之前通知您。
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的解決方案:使用堆內存分配的大型陣列
添加回答
舉報
