इस व्यवहार के लिए सबसे संभावित कारण यह है कि आपकी स्टैक आकार सीमा बहुत छोटी है (किसी भी कारण से)। चूंकि e_in
प्रत्येक ओपनएमपी थ्रेड के लिए निजी है, इसलिए थ्रेड स्टैक पर एक प्रति प्रति थ्रेड आवंटित किया गया है (भले ही आपने -heap-arrays
निर्दिष्ट किया हो!)। 202000
REAL(KIND=8)
के तत्व 1616 केबी (या 1579 कीबी) लेते हैं।
ढेर आकार की सीमा कई तंत्रों के द्वारा नियंत्रित किया जा सकता है:
मानक यूनिक्स प्रणाली के गोले पर ढेर आकार की राशि ulimit -s <stacksize in KiB>
द्वारा नियंत्रित है। यह मुख्य ओपनएमपी थ्रेड के लिए स्टैक आकार सीमा भी है। इस सीमा का मान POSIX थ्रेड (pthreads
) लाइब्रेरी द्वारा नए धागे बनाते समय डिफ़ॉल्ट थ्रेड स्टैक आकार के रूप में भी प्रयोग किया जाता है।
ओपनएमपी अतिरिक्त थ्रेड के पर्यावरण चर OMP_STACKSIZE
के माध्यम से स्टैक आकार सीमा पर नियंत्रण का समर्थन करता है। इसकी मान एक वैकल्पिक प्रत्यय k
/K
केबी, m
/M
एफआईआरआई एमआईबी, या g
/G
के लिए जीआईबी के लिए एक संख्या है। यह मान मुख्य धागे के ढेर आकार को प्रभावित नहीं करता है।
जीएनयू ओपनएमपी रन-टाइम (libgomp
) गैर मानक पर्यावरण चर GOMP_STACKSIZE
पहचानता है। यदि सेट किया गया है तो यह OMP_STACKSIZE
के मान को ओवरराइड करता है।
इंटेल ओपनएमपी रन-टाइम गैर-मानक पर्यावरण परिवर्तनीय KMP_STACKSIZE
को मान्यता देता है। यदि सेट किया गया है तो यह OMP_STACKSIZE
के मान को ओवरराइड करता है और GOMP_STACKSIZE
के मान को ओवरराइड करता है यदि संगतता ओपनएमपी रन-टाइम का उपयोग किया जाता है (जो वर्तमान में केवल उपलब्ध इंटेल ओपनएमपी रन-टाइम लाइब्रेरी compat
एक डिफ़ॉल्ट है)।
*_STACKSIZE
चर का कोई भी सेट कर रहे हैं, इंटेल OpenMP रन-टाइम के लिए डिफ़ॉल्ट 32-बिट आर्किटेक्चर पर 2m
और 4m
64-बिट वालों पर है।
विंडोज़ पर, मुख्य धागे का ढेर आकार पीई हेडर का हिस्सा है और लिंकर द्वारा वहां एम्बेड किया गया है। यदि लिंक करने के लिए माइक्रोसॉफ्ट के LINK
का उपयोग करते हैं, तो आकार /STACK:reserve[,commit]
का उपयोग करके निर्दिष्ट किया गया है। reserve
तर्क बाइट्स में अधिकतम स्टैक आकार निर्दिष्ट करता है जबकि वैकल्पिक commit
तर्क प्रारंभिक प्रतिबद्ध आकार निर्दिष्ट करता है। दोनों को 0x
उपसर्ग का उपयोग करके हेक्साडेसिमल मानों के रूप में निर्दिष्ट किया जा सकता है।यदि निष्पादन योग्य को पुनः लिंक करना एक विकल्प नहीं है, तो पीई हेडर को EDITBIN
के साथ संपादित करके स्टैक आकार को संशोधित किया जा सकता है। यह लिंकर के रूप में एक ही स्टैक-संबंधित तर्क लेता है। एमएसवीसी के पूरे कार्यक्रम अनुकूलन सक्षम (/GL
) के साथ संकलित प्रोग्राम संपादित नहीं किए जा सकते हैं।
Win32 लक्ष्यों के लिए जीएनयू लिंकर --stack
तर्क के माध्यम से स्टैक आकार को सेट करने का समर्थन करता है। सीधे जीसीसी से विकल्प पास करने के लिए, -Wl,--stack,<size in bytes>
का उपयोग किया जा सकता है।
ध्यान दें कि धागा ढेर वास्तव में आकार *_STACKSIZE
द्वारा निर्धारित (या डिफ़ॉल्ट मान पर) के साथ आवंटित कर रहे हैं, मुख्य थ्रेड के ढेर है, जो छोटे शुरू होता है और फिर मांग पर सेट करने के लिए बढ़ता है के विपरीत सीमा। इसलिए *_STACKSIZE
को मनमाने ढंग से बड़े मान पर सेट न करें अन्यथा आप वर्चुअल मेमोरी आकार सीमा को प्रभावित कर सकते हैं।
यहाँ कुछ उदाहरण हैं:
$ ifort -openmp my_module.f90 main.f90
सेट 1 MiB करने के लिए मुख्य ढेर आकार सीमा (अतिरिक्त OpenMP धागा 4 MiB डिफ़ॉल्ट के अनुसार मिलेगा):
$ ulimit -s 1024
$ ./a.out
zsh: segmentation fault (core dumped) ./a.out
मुख्य ढेर सेट 1700 किबा के लिए आकार सीमा:
$ 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 को dditional धागा:
$ ulimit -s 2048
$ KMP_STACKSIZE=1m ./a.out
zsh: segmentation fault (core dumped) KMP_STACKSIZE=1m ./a.out
सबसे यूनिक्स प्रणालियों पर मुख्य थ्रेड के ढेर आकार सीमा पीएएम या अन्य प्रवेश तंत्र (/etc/security/limits.conf
देखें) द्वारा निर्धारित है। वैज्ञानिक लिनक्स 6.3 पर डिफ़ॉल्ट 10 एमआईबी है।
एक और संभावित परिदृश्य जो त्रुटि का कारण बन सकता है यदि वर्चुअल एड्रेस स्पेस सीमा बहुत कम है। उदाहरण के लिए, यदि वर्चुअल एड्रेस स्पेस सीमा 1 जीबीबी है और थ्रेड स्टैक आकार सीमा 512 एमआईबी पर सेट है, तो ओपनएमपी रन-टाइम प्रत्येक अतिरिक्त थ्रेड के लिए 512 एमआईबी आवंटित करने का प्रयास करेगा। दो धागे के साथ केवल स्टैक्स के लिए 1 जीबीबी होगा, और जब कोड के लिए स्थान, साझा पुस्तकालय, ढेर इत्यादि जोड़ा जाता है, वर्चुअल मेमोरी आकार 1 जीबीबी से आगे बढ़ेगा और एक त्रुटि होगी:
1 GiB के लिए वर्चुअल पता स्थान सीमा निर्धारित करें और 512 MiB के ढेर के साथ दो अतिरिक्त धागे (मैं omp_set_num_threads()
करने के लिए कॉल बाहर टिप्पणी की है) के साथ चलाएँ:
$ ulimit -v 1048576
$ KMP_STACKSIZE=512m OMP_NUM_THREADS=3 ./a.out
OMP: Error #34: System unable to allocate necessary resources for OMP thread:
OMP: System error #11: Resource temporarily unavailable
OMP: 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 रन-टाइम पुस्तकालय बनाने के लिए विफल हो जाएगा में एक नया धागा और कार्यक्रम समाप्त होने से पहले आपको सूचित करेगा।
मैं याद नहीं सोचा था कि, यह है कि इन सरणियों सिर्फ 2 तत्व हैं।वैसे भी मैं अक्सर परिमाण के आदेशों से बड़े सरणी के साथ -स्टैक-एरे का उपयोग करता हूं। लेकिन इफोर्ट के साथ नहीं। –
यह थोड़ा उलझन में है कि 'gfortran' और' ifort' दोनों के साथ स्थैतिक सरणी की निजी प्रतियां हमेशा स्वचालित होती हैं और किसी भी कंपाइलर विकल्पों के बावजूद थ्रेड स्टैक पर आवंटित होती हैं जो नियमित सरणी के प्लेसमेंट को प्रभावित कर सकती हैं। –