ओएस थ्रेड अनुसूचक से उत्पन्न नॉनडेटर्मिनिज़म को उजागर करें


10

जैसा कि हम सभी जानते हैं कि आधुनिक ऑपरेटिंग सिस्टम में थ्रेड शेड्यूलर होते हैं जो आंतरिक तर्क के आधार पर आपके थ्रेड को शेड्यूल करने के लिए अलग-अलग ऑर्डर ले सकते हैं जो कि आपके कोड के लिए निजी नहीं है। आम तौर पर आप अपने मल्टीथ्रेडेड कोड को आर्किटेक्ट करते हैं ताकि यह सुनिश्चित किया जा सके कि आपके द्वारा लगाया गया यह नॉनटर्मिनिज्म सार्थक रूप से आपके आउटपुट को प्रभावित नहीं करता है।

यहां लक्ष्य विपरीत है। एक प्रोग्राम का निर्माण करें जो पूर्णांक को अंतराल [0,99] में प्रिंट करता है, लेकिन एक क्रम में जो ओएस थ्रेड शेड्यूलर के कारण रन से चलाने के लिए अलग-अलग होगा।

आपको "पर्याप्त नॉनडेर्मिनिज़्म" प्राप्त करना होगा, जिसे इस प्रकार परिभाषित किया गया है:

10 परीक्षणों के 10 अनुक्रमिक सेटों में आपके कार्यक्रम को प्रत्येक परीक्षण के भीतर कम से कम 9 अद्वितीय क्रमपरिवर्तन का उत्पादन करना चाहिए। आपके पास लगातार 10 के दोनों तरफ परीक्षणों के असफल सेटों की एक उचित संख्या हो सकती है जो सफल होते हैं।

या, इसे दूसरे तरीके से रखने के लिए, आपको अपने कार्यक्रम के 100 रनों की आवश्यकता होती है, जहां 10 रनों के प्रत्येक ब्लॉक में अधिकतम दो रन होते हैं जो एक ही चीज़ का उत्पादन करते हैं।

इसलिए, कभी-कभी 98 और 99 की अदला-बदली होती है।

यह एक , इसलिए इसका उत्तर जो सबसे कम बाइट्स जीतता है।

ज़रा सी बात

  • अपने आउटपुट को स्टैडआउट में लिखें, प्रति पंक्ति एक प्रविष्टि
  • यदि आप दो थ्रेड्स के माध्यम से प्रारूप को नियंत्रित करते हैं तो इंटरलेव चरित्र stdout को (यहां तक ​​कि कभी-कभी) लिखते हैं जिसके परिणामस्वरूप तीन अंकों की संख्या या खाली लाइनें जैसी चीजें होती हैं, आपका परिणाम अमान्य है
  • उपरोक्त नियम का एकमात्र अपवाद यह है कि अंतिम आवश्यक संख्या को प्रिंट करने के बाद आप एक खाली लाइन का उत्सर्जन कर सकते हैं (आपका स्वागत है)
  • यदि आप कभी भी किसी भी आवश्यक मूल्यों को याद या डुप्लिकेट करते हैं तो आपका परिणाम अमान्य है
  • आपके कार्यक्रम को एक ही कोर प्रोसेसर पर (हालांकि कुडोस अगर ऐसा है तो) nondeterministic होने की आवश्यकता नहीं है
  • आपका कार्यक्रम हरे रंग के धागे / फाइबर का उपयोग कर सकता है जो वास्तव में ओएस कर्नेल द्वारा प्रबंधित नहीं किया जाता है यदि यह अभी भी चुनौती की अन्य आवश्यकताओं को पूरा करता है और थ्रेडिंग सिस्टम आपकी भाषा का हिस्सा है या आपकी भाषा के लिए मानक पुस्तकालय
  • आपके प्रोग्राम के लिए रनटाइम को आधुनिक प्रोसेसर पर 5 सेकंड के तहत मज़बूती से होना चाहिए
  • आपको अपने प्रोग्राम के बाहर होने वाले वातावरण जैसे परिवर्तन की प्रतीक्षा करने या सेटिंग्स में परिवर्तन करने के लिए नहीं मिलता है; आपके कार्यक्रम को पास होना चाहिए कि क्या 100 बार बार बैक टू बैक या प्रत्येक रन के बीच में एक घंटे के साथ या 100 बार समानांतर में होगा (जो कि वास्तव में होगा ...)
  • आप कार्यों के लिए GPU या Xeon Phi और अपने स्वयं के आंतरिक शेड्यूलिंग तंत्र जैसे एक कॉपीप्रोसेसर का उपयोग कर सकते हैं। नियम उसी तरह से लागू होते हैं जिस तरह वे हरे धागे पर लागू होते हैं।
  • जब तक आप इस पद के नियमों का पालन करते हैं, तब तक सभी प्रकार की नींद, पैदावार और अन्य चाल के साथ अनुसूचक को भड़काने के लिए स्वतंत्र महसूस करें

संचालन पर प्रतिबंध लगा दिया

नॉनडेटर्मिनिज़्म का एकमात्र स्रोत जिस पर आपको आकर्षित करने की अनुमति है, जब शेड्यूलर आपके थ्रेड को चलाने के लिए शेड्यूल करता है। निम्नलिखित सूची संपूर्ण नहीं है, केवल उन चीज़ों के उदाहरण प्रदान करने के लिए जिन्हें आप करने की अनुमति नहीं है क्योंकि वे नोंदेर्मेरिनिज़्म के अन्य स्रोतों को स्वीकार करते हैं।

  • किसी भी प्रकार की PRNG या हार्डवेयर RNG क्षमता का प्रत्यक्ष या अप्रत्यक्ष रूप से उपयोग करना (जब तक कि यह अनुसूचक के निहित भाग के रूप में नहीं है)।
  • किसी भी तरह के इनपुट (सिस्टम समय, फाइल सिस्टम, नेटवर्क, आदि) में पढ़ना
  • थ्रेड आईडी या प्रोसेस आईडी पढ़ना
  • ओएस अनुसूचक को अनुकूलित करना; आपको एक मुख्यधारा ओएस से एक मानक ओएस अनुसूचक का उपयोग करना चाहिए
  • अपने हरे धागे / फाइबर अनुसूचक को अनुकूलित करना भी निषिद्ध है। इसका मतलब है कि यदि आप इस चुनौती के लिए भाषा लिखते हैं तो आपको ओएस थ्रेड का उपयोग करना होगा

उत्तर मान्यता

अधिमानतः एक उत्तर सभी सामान्य ओएस और आधुनिक प्रोसेसर पर काम करेगा, जिसमें कुडोस को समर्थन की चौड़ाई के आनुपातिक रूप से सम्मानित किया जाएगा। हालाँकि, यह चुनौती की आवश्यकता नहीं है। कम से कम एक उत्तर में एक आधुनिक एसएमपी प्रोसेसर और आधुनिक ओएस का समर्थन करना चाहिए। मैं अपनी हार्डवेयर उपलब्धता की सीमा तक प्रमुख उत्तरों का परीक्षण करूँगा।

  • यदि आपकी प्रविष्टि विंडोज 10 v1607 x64 पर चलने वाले i7 5960x पर आवश्यक आउटपुट नहीं देगी, तो आवश्यक पर्यावरण निर्दिष्ट करें
  • यदि यह ऐसा कुछ है जिसे मैं VMWare वर्कस्टेशन के साथ आसानी से पुन: पेश कर सकता हूं, तो सटीक ओएस और वीएम चश्मा प्रदान करें
  • यदि यह उन स्थितियों में से किसी में भी उत्पादन नहीं किया जा सकता है, तो हेडर सेक्शन में वर्णित परीक्षण की एक साथ स्क्रीन कैप्चर रिकॉर्ड करें और अपने माउस और कीबोर्ड इंटरैक्शन (या जो भी नियंत्रण योजना आपकी गैर-अभिकलन संगणना है) के साथ आपकी स्क्रीन की एक हैंडहेल्ड वीडियो रिकॉर्डिंग करें। डिवाइस का उपयोग करता है) स्पष्ट रूप से दिखाई देता है और अपने उत्तर के साथ दोनों वीडियो पोस्ट करता है और इसमें यह व्याख्या करता है कि यह क्यों काम करता है
  • वैकल्पिक रूप से, एक प्रतिष्ठित लंबे समय से स्थायी उपयोगकर्ता (जो आप नहीं हैं) को परिणाम के लिए पुन: उत्पन्न करने के लिए मेल खाते हार्डवेयर के साथ और आपके लिए वाउचर प्राप्त करें
  • यदि आपकी प्रविष्टि एक विदेशी प्रोग्रामिंग भाषा में है, जो सेटअप निर्देशों को संकलित / जिट / व्याख्या करने के लिए एक विशिष्ट डेवलपर स्थापित नहीं किया जाएगा
  • यदि आप प्रवेश JVM / Python दुभाषिया / अन्य के एक विशिष्ट संस्करण पर निर्भर करते हैं, तो निर्दिष्ट करें
  • अगर मेरे परीक्षण में आपके 10 सफल अनुक्रमिक सेट प्राप्त करने के लिए 10 मिनट से अधिक समय तक बैक-टू-बैक रन लेता है, तो आप असफल हो जाते हैं (इसलिए सफलता की स्थिति एक सनकी घटना न होने दें, खासकर यदि आप ऊपरी के पास हों रनटाइम बाउंड)

4
-1 के लिए "अगर मैं ऊब गया ...."। मैं कहता हूँ कि यह कितना समय लग सकता है।
R

@EasterlyIrk यह भी कहते हैं, 'मज़बूती से पाँच सेकंड के तहत एक आधुनिक CPU पर'
पावेल

@ यह बताएं कि मैं क्या नहीं कर रहा हूं। 10 सफल परीक्षण 5 सेकंड से संबंधित नहीं हैं।
R

@EasterlyIrk फेयर काफी, अब 10 मिनट है।
Techrocket9

@ Techrocket9 कूल, डाउनवोट रिजेक्टेड।
R

जवाबों:


4

पर्ल 6 , 27 बाइट्स

await map {start .say},^100

स्पष्टीकरण:

      map {          },^100  # Iterate over the range 0..99, and for each of number:
           start             # Send the following task to a thread pool of OS threads:
                 .say        # Print the number, followed by a newline.
await                        # Wait until all tasks have completed.

मुझे उम्मीद है कि यह कार्य को पूरा करेगा। (यदि नहीं, तो कृपया मुझे बताएं)।

परिक्षण:

शेल स्क्रिप्ट मैं पर्याप्त नॉनडेटर्मिनिज़्म का परीक्षण करता था:

#!/usr/bin/bash
for i in {1..10}; do
    set=""
    for j in {1..10}; do
        set="${set}$(perl6 nondet.p6 | tr '\n' ',')\n"
    done
    permutations="$(echo -e "$set" | head -n -1 | sort | uniq | wc -l)"
    echo -n "$permutations "
done

मेरे लिए, यह आउटपुट:

10 10 10 10 10 10 10 10 10 10 

सेटअप निर्देश:

मैंने 64 बिट लिनक्स पर एक अप-टू-डेट Rakudo Perl 6 के साथ परीक्षण चलाया, हालांकि मुझे लगता है कि यह अन्य प्लेटफार्मों पर काम करेगा।

Rakudo डाउनलोड पृष्ठ सेटअप निर्देशों का है। मैं इस तरह से मेरा संकलन:

git clone git@github.com:rakudo/rakudo.git
cd rakudo
perl Configure.pl --gen-moar --make-install
export PATH="$(pwd)/install/bin/:$PATH"

इसे ऑनलाइन आज़माएँ:

या सिर्फ इसे ऑनलाइन परीक्षण करें , इस प्रयास का उपयोग करके @ b2gills द्वारा प्रदान किया गया ऑनलाइन लिंक। मैंने कुछ रनों की जाँच की और हर बार एक अलग क्रम प्राप्त किया, लेकिन उस ऑनलाइन इंटरफ़ेस के माध्यम से इसे 100 बार चलाने का धैर्य नहीं था।



Rakudo Perl संस्करण 2016.11 के साथ i7 5960x पर विंडोज 10 x64 पर मान्य
Techrocket9

4

बैश, 32 28 बाइट्स

for i in {0..99};{ echo $i&}

मैंने इसे 100 बार चलाया और 100 अलग-अलग परिणाम मिले।

संपादित करें: @DigitalTrauma के लिए धन्यवाद 4 बाइट्स सहेजे गए।


आपने मुझे इसमें हरा दिया। वास्तव में मेरा एक छोटा सा छोटा है for i in {0..99};{ echo $i&}, लेकिन आपने पहले पोस्ट किया है - आप इसे ले सकते हैं :)
डिजिटल ट्रामा

यहाँ एक तरीका है जिससे आप TIO में इसका परीक्षण कर सकते हैं। यह स्क्रिप्ट के 10 रन करता है, प्रत्येक रन से आउटपुट कैप्चर करता है, वे प्रत्येक रन से आउटपुट को md5ing करता है। हम देख सकते हैं कि md5 हर बार अलग होते हैं। Md5s को संभावित डुप्लिकेट को स्पष्ट करने के लिए हल किया जाता है।
डिजिटल ट्रॉमा

@DigitalTrauma अनपढ़ लेकिन अच्छा!
नील

1
हां - इसके लिए एक टिप है।
डिजिटल ट्रॉमा

दिलचस्प है, यह एक E5-2699 v4 पर Microsoft के आधिकारिक बैश-ऑन-विंडोज में चलने पर "पर्याप्त नॉनडेटर्मिनिज़्म" प्राप्त करने में विफल रहता है, लेकिन यह RHEL वर्कस्टेशन VM में उसी मशीन पर 4 कोर के साथ काम करता है जिससे वह गुजरता है।
Techrocket9

2

पॉवरशेल , 54 46 44 39 बाइट्स

workflow p{foreach -p($i in 0..99){$i}}

पॉवरशेल वर्कफ़्लो TIO में समर्थित नहीं हैं, इसलिए आप इसे वहां नहीं आज़मा सकते। अपने विंडोज 10 मशीन पर महान काम करना चाहिए, हालांकि :)

एक फ़ंक्शन को परिभाषित करता है pजो संख्याओं की सूची का उत्पादन करेगा जब आह्वान किया जाएगा।

समय

एक एकल रन मज़बूती से मेरी मशीन पर लगभग 600ms में चलता है। नीचे दिए गए 100 परीक्षण 2 मिनट से कम समय में समाप्त हो जाते हैं।

परिक्षण

इसका परीक्षण करने के लिए यहां पूरा कोड है:

workflow p{foreach -p($i in 0..99){$i}}
#workflow p{foreach($i in 0..99){$i}}
# uncomment above to prove testing methodology does detect duplicates

1..10 | % {
    $set = $_
    Write-Host "Set $set of 10"
    1..10 | % -b {
        $runs = @()
    } -p {
        $run = $_
        Write-Host "-- Run $run of 10 in set $set"
        $runs += "$(p)"
    } -e {
        Write-Host "-- There were $(10-($runs|Get-Unique).Count) duplicate runs in set $set"
    }
}

मेरी मशीन पर आउटपुट:

Set 1 of 10
-- Run 1 of 10 in set 1
-- Run 2 of 10 in set 1
-- Run 3 of 10 in set 1
-- Run 4 of 10 in set 1
-- Run 5 of 10 in set 1
-- Run 6 of 10 in set 1
-- Run 7 of 10 in set 1
-- Run 8 of 10 in set 1
-- Run 9 of 10 in set 1
-- Run 10 of 10 in set 1
-- There were 0 duplicate runs in set 1
Set 2 of 10
-- Run 1 of 10 in set 2
-- Run 2 of 10 in set 2
-- Run 3 of 10 in set 2
-- Run 4 of 10 in set 2
-- Run 5 of 10 in set 2
-- Run 6 of 10 in set 2
-- Run 7 of 10 in set 2
-- Run 8 of 10 in set 2
-- Run 9 of 10 in set 2
-- Run 10 of 10 in set 2
-- There were 0 duplicate runs in set 2
Set 3 of 10
-- Run 1 of 10 in set 3
-- Run 2 of 10 in set 3
-- Run 3 of 10 in set 3
-- Run 4 of 10 in set 3
-- Run 5 of 10 in set 3
-- Run 6 of 10 in set 3
-- Run 7 of 10 in set 3
-- Run 8 of 10 in set 3
-- Run 9 of 10 in set 3
-- Run 10 of 10 in set 3
-- There were 0 duplicate runs in set 3
Set 4 of 10
-- Run 1 of 10 in set 4
-- Run 2 of 10 in set 4
-- Run 3 of 10 in set 4
-- Run 4 of 10 in set 4
-- Run 5 of 10 in set 4
-- Run 6 of 10 in set 4
-- Run 7 of 10 in set 4
-- Run 8 of 10 in set 4
-- Run 9 of 10 in set 4
-- Run 10 of 10 in set 4
-- There were 0 duplicate runs in set 4
Set 5 of 10
-- Run 1 of 10 in set 5
-- Run 2 of 10 in set 5
-- Run 3 of 10 in set 5
-- Run 4 of 10 in set 5
-- Run 5 of 10 in set 5
-- Run 6 of 10 in set 5
-- Run 7 of 10 in set 5
-- Run 8 of 10 in set 5
-- Run 9 of 10 in set 5
-- Run 10 of 10 in set 5
-- There were 0 duplicate runs in set 5
Set 6 of 10
-- Run 1 of 10 in set 6
-- Run 2 of 10 in set 6
-- Run 3 of 10 in set 6
-- Run 4 of 10 in set 6
-- Run 5 of 10 in set 6
-- Run 6 of 10 in set 6
-- Run 7 of 10 in set 6
-- Run 8 of 10 in set 6
-- Run 9 of 10 in set 6
-- Run 10 of 10 in set 6
-- There were 0 duplicate runs in set 6
Set 7 of 10
-- Run 1 of 10 in set 7
-- Run 2 of 10 in set 7
-- Run 3 of 10 in set 7
-- Run 4 of 10 in set 7
-- Run 5 of 10 in set 7
-- Run 6 of 10 in set 7
-- Run 7 of 10 in set 7
-- Run 8 of 10 in set 7
-- Run 9 of 10 in set 7
-- Run 10 of 10 in set 7
-- There were 0 duplicate runs in set 7
Set 8 of 10
-- Run 1 of 10 in set 8
-- Run 2 of 10 in set 8
-- Run 3 of 10 in set 8
-- Run 4 of 10 in set 8
-- Run 5 of 10 in set 8
-- Run 6 of 10 in set 8
-- Run 7 of 10 in set 8
-- Run 8 of 10 in set 8
-- Run 9 of 10 in set 8
-- Run 10 of 10 in set 8
-- There were 0 duplicate runs in set 8
Set 9 of 10
-- Run 1 of 10 in set 9
-- Run 2 of 10 in set 9
-- Run 3 of 10 in set 9
-- Run 4 of 10 in set 9
-- Run 5 of 10 in set 9
-- Run 6 of 10 in set 9
-- Run 7 of 10 in set 9
-- Run 8 of 10 in set 9
-- Run 9 of 10 in set 9
-- Run 10 of 10 in set 9
-- There were 0 duplicate runs in set 9
Set 10 of 10
-- Run 1 of 10 in set 10
-- Run 2 of 10 in set 10
-- Run 3 of 10 in set 10
-- Run 4 of 10 in set 10
-- Run 5 of 10 in set 10
-- Run 6 of 10 in set 10
-- Run 7 of 10 in set 10
-- Run 8 of 10 in set 10
-- Run 9 of 10 in set 10
-- Run 10 of 10 in set 10
-- There were 0 duplicate runs in set 10

दिलचस्प है, यह मेरे E5-2699 v4 बॉक्स पर प्रति रन 51 सेकंड लेता है, लेकिन मेरे i5-5200U लैपटॉप पर केवल .7 सेकंड। यह 5 सेकंड के अधिकतम के तहत आने के दौरान लैपटॉप पर नॉनडेटर्मिनिज़म की आवश्यक डिग्री प्राप्त करता है, इसलिए यह गुजरता है। जाहिरा तौर पर, PowerShell का शेड्यूलर कई कोर और छोटे कार्यों के साथ अच्छा नहीं खेलता है।
Techrocket9

और i7 5960x पर 58 सेकंड लगते हैं
Techrocket9

हम्म ... एक i5-6300U लैपटॉप पर 74 सेकंड। शायद यह विंडोज 10 या पावरशेल 5.1 के साथ एक समस्या है, क्योंकि i5-5200U केवल उन मशीनों में से एक है जो Win10 नहीं चला रहे हैं (यह 8.1 चला रहा है)।
Techrocket9

@ Techrocket9 अजीब, मैं Win10, PS 5.1 पर परीक्षण कर रहा था। हालांकि ISE में।
रिश्वतवादी

2

लिनक्स पर जीसीसी, 47 बाइट्स

main(i){for(i=99;fork()?i--:!printf("%d\n",i););}

यह मुझे हर बार अलग-अलग परिणाम देता है, gcc4.9.2 संस्करण (झंडे नहीं) के साथ संकलित किया गया है । विशेष रूप से, मैं 64-बिट डेबियन 8.6 (कर्नेल संस्करण 3.16.31) पर था।

व्याख्या

यदि fork()रिटर्न शून्य (चाइल्ड प्रोसेस) है, तो वैल्यू iप्रिंटेड है, और लूप की स्थिति झूठी है, क्योंकि printfयह शून्य से अधिक मूल्य लौटाएगा। मूल प्रक्रिया में, लूप स्थिति बस है i--


बैश जवाब के रूप में भी। खिड़कियों पर नियतात्मक, लेकिन लिनक्स पर (इस मामले में डेबियन)।
Techrocket9
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.