OS iş parçacığı zamanlayıcıdan kaynaklanan belirsizliği ortaya çıkarma


10

Hepimizin bildiği gibi, modern işletim sistemleri, kodlarınızı özel olmayan iç mantığa göre iş parçacıklarınızı planlamak için farklı siparişler seçebilen iş parçacığı zamanlayıcılarına sahiptir. Normalde, size uygulanan bu belirsizliğin çıktınızı önemli ölçüde etkilemediğinden emin olmak için çok iş parçacıklı kodunuzu tasarlarsınız.

Buradaki amaç tam tersidir. Tamsayıları [0,99] aralığında, ancak işletim sistemi iş parçacığı zamanlayıcısı nedeniyle çalıştırmadan çalışmaya değişen bir sırayla yazdıran bir program oluşturun.

Şu şekilde tanımlanan "yeterince belirsizliği" yakalamanız gerekir:

10 denemeden oluşan 10 ardışık sette, programınız her denemede en az 9 benzersiz permütasyon üretmelidir. Ardışık 10'un her iki tarafında da başarılı sayıda başarısız deneme setiniz olabilir.

Ya da başka bir deyişle, 10 çalışmanın her bloğunun aynı şeyi veren en fazla iki çalışmanın olduğu 100 programa ihtiyacınız vardır.

Yani, bazen 98 ve 99'u değiştirmek onu kesmez.

Bu bir , bu yüzden en az bayt kullanan cevap kazanır.

Önemsiz ayrıntılar

  • Çıktınızı her satıra bir giriş olacak şekilde stdout'a yazın
  • Biçimi iki basamaklı serpiştirme karakterine stdout'a (bazen de) yazarak üç basamaklı sayı veya boş satır gibi şeylerle sonuçlanırsanız, sonucunuz geçersizdir
  • Yukarıdaki kuralın tek istisnası, gerekli son numarayı yazdırdıktan sonra tek bir boş satır yayınlayabilmenizdir (hoş geldiniz)
  • Gerekli değerleri kaçırır veya çoğaltırsanız sonucunuz geçersizdir
  • Programınız yok değil (öyle şeref eğer rağmen) tek çekirdekli işlemci üzerinde nondeterministic olmak gerekir
  • Programınız, işletim sisteminin çekirdeği tarafından yönetilmeyen yeşil iplikler / lifler kullanabilir, ancak yine de zorluğun diğer gereksinimlerini karşılarsa ve diş açma sistemi dilinizin bir parçasıdır veya diliniz için standart kitaplıktır
  • Modern bir işlemci üzerinde programınızın çalışma süresi 5 saniyenin altında olmalıdır
  • Programınızın dışında gerçekleşen, beklemeler veya ayar değişiklikleri gibi ortam değişikliklerini belirtemezsiniz; programınız ister 100ish kez arka arkaya ister her çalışma arasında bir saat veya paralel olarak 100ish kez çalışsın (muhtemelen yardımcı olacaktır ...)
  • GPU veya Xeon Phi gibi bir işlemciyi ve görevler için kendi dahili zamanlama mekanizmasını kullanabilirsiniz. Kurallar bunun için yeşil iplikler için geçerli olduğu gibi geçerlidir.
  • Bu yayında belirtilen kurallara uyduğunuz sürece, programlayıcıyı her türlü uyku, verim ve diğer hilelerle provoke etmekten çekinmeyin.

Yasaklanan İşlemler

Çizmenize izin verilen tek bir belirsizliğin kaynağı, zamanlayıcının iş parçacıklarınızın çalışması için zamanlamasıdır. Aşağıdaki liste ayrıntılı değildir, yalnızca diğer belirsiz olmayan kaynakları kabul ettikleri için yapmanıza izin verilmeyen şeylerin örneklerini sağlamayı amaçlamaktadır.

  • Doğrudan veya dolaylı olarak herhangi bir PRNG veya donanım RNG yeteneğine erişme (zamanlayıcının doğal bir parçası olmadığı sürece).
  • Her türlü girişte okuma (sistem zamanı, dosya sistemi, ağ vb.)
  • İş parçacığı kimliklerini veya işlem kimliklerini okuma
  • İşletim sistemi zamanlayıcısını özelleştirme; genel bir işletim sisteminden standart bir işletim sistemi zamanlayıcı kullanmalısınız
  • Yeşil iplik / fiber zamanlayıcıyı özelleştirmek de yasaktır. Bu, bu meydan okuma için bir dil yazarsanız , OS iş parçacıklarını kullanmanız gerektiği anlamına gelir .

Yanıt Doğrulama

Tercihen bir cevap, tüm yaygın işletim sistemlerinde ve modern işlemcilerde işe yarar, kudolar destek genişliği ile orantılı olarak verilir. Ancak, bu zorluğun bir gereği değildir. En azından bir cevap bir modern SMP işlemciyi ve modern işletim sistemini desteklemelidir. Donanım kullanılabilirliğimin ölçüsünde ölçülen yanıtları test edeceğim.

  • Girişiniz Windows 10 v1607 x64 çalıştıran bir i7 5960x'de gerekli çıkışı üretmezse, gerekli ortamı belirtin
  • VMWare Workstation ile kolayca üretebileceğim bir şeyse, tam OS ve VM özelliklerini sağlayın
  • Bu koşullardan herhangi birinde üretilemiyorsa, testin başlık bölümünde açıklandığı gibi eşzamanlı bir ekran görüntüsünü ve fare ve klavye etkileşiminizle (veya standart olmayan hesaplamanızın kontrol düzeni ne olursa olsun) ekranınızın elde taşınır video kaydını kaydedin cihaz kullanımları) açıkça görülebilir ve her iki videoyu da cevabınızla birlikte gönderin ve neden çalıştığına dair bir açıklama ekleyin
  • Alternatif olarak, sonucu yeniden oluşturmak ve sizin için kefil olmak için uygun donanıma sahip saygın ve uzun süredir devam eden bir kullanıcı (kim siz değilsiniz) alın
  • Girişiniz, tipik bir geliştiricinin derleme / jit / yorumlama için ayarlanmayacağı egzotik bir programlama dilinde ise kurulum talimatlarını sağlayın
  • Giriş JVM / Python yorumlayıcısının / diğer sürümünün belirli bir sürümüne bağlıysa,
  • Testlerimde 10 başarılı ardışık deneme setinizi elde etmek için 10 dakikadan fazla arka arkaya çalışma süreniz başarısız olursa (bu nedenle, özellikle üste yakınsanız, başarı durumunun bir ucube olmasına izin vermeyin çalışma zamanı bağlı)

4
-1 "sıkılırsam ....". Tam olarak ne kadar süreceğini belirtin.
Rɪᴋᴇʀ

@EasterlyIrk Ayrıca 'modern bir CPU'da beş saniyenin altında güvenilir bir şekilde' diyor
Pavel

@Pavel, bahsettiğim şey bu değil. Başarılı 10 deneme 5 saniye ile ilgili değildir.
Rɪᴋᴇʀ

@EasterlyIrk Yeterince adil, şimdi 10 dakika.
Techrocket9

@ Techrocket9 cool, downvote iptal edildi.
Rɪᴋᴇʀ

Yanıtlar:


4

Perl 6 , 27 bayt

await map {start .say},^100

Açıklama:

      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.

Umarım bu görevi yerine getirir. (Eğer değilse, lütfen beni bilgilendir).

Test yapmak:

Yeterli belirsizliği test etmek için kullandığım kabuk betiği:

#!/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

Benim için bu çıktı:

10 10 10 10 10 10 10 10 10 10 

Kurulum talimatları:

Testi 64bit Linux'ta güncel bir Rakudo Perl 6 ile çalıştırdım, ancak sanırım diğer platformlarda da çalışacak.

Rakudo indirme sayfası kurulum talimatlar bulunur. Benimkini git gibi derledim:

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

Çevrimiçi deneyin:

Veya @ b2gills tarafından sağlanan bu Çevrimiçi Dene bağlantısını kullanarak çevrimiçi test edebilirsiniz. Birkaç koşuyu kontrol ettim ve her seferinde farklı bir sipariş aldım, ancak bu çevrimiçi arayüz üzerinden 100 kez çalıştırmak için sabrım olmadı.



Rakudo Perl sürüm 2016.11 ile i7 5960x üzerinde Windows 10 x64 üzerinde doğrulandı
Techrocket9

4

bash, 32 28 bayt

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

Bunu 100 kez çalıştırdım ve 100 farklı sonuç aldım.

Düzenleme: @DigitalTrauma sayesinde 4 bayt kaydedildi.


Beni dövüyorsun. Aslında benimki biraz daha kısa for i in {0..99};{ echo $i&}, ama önce yayınladın - alabilirsin :)
Digital Trauma

İşte TIO'da test etmenin bir yolu . Bu, komut dosyasının 10 çalışmasını gerçekleştirir, her çalışmadan çıktı yakalar, her çalışmadan çıktıyı md5ing eder. Md5'lerin her seferinde farklı olduğunu görebiliriz. Md5'ler, olası kopyaları görünür hale getirmek için sıralanır.
Dijital Travma

@DigitalTrauma Belgelenmemiş ama güzel!
Neil

1
Evet - bunun için bir ipucu var .
Dijital Travma

İlginç bir şekilde, bu, Microsoft'un E5-2699 v4'te resmi bash-on-windows'ında çalıştırıldığında "yeterince belirsizliği" elde edemez, ancak aynı makinede 4 çekirdekli bir RHEL İş İstasyonu VM'sinde çalışır, böylece geçer.
Techrocket9

2

PowerShell , 54 46 44 39 bayt

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

PowerShell İş Akışları TIO'da desteklenmediği için orada deneyemezsiniz. Windows 10 makinenizde harika çalışmalı :)

Çağrıldığında psayıların listesini çıkaracak bir işlev tanımlar .

Zamanlama

Tek bir çalışma, makinemde yaklaşık 600ms'de güvenilir bir şekilde çalışır. Aşağıda tanımlanan 100 test 2 dakikadan kısa sürede sona erer.

Test yapmak

Test etmek için tam kod:

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"
    }
}

Makinemdeki çıktı:

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

İlginçtir, bu E5-2699 v4 kutumda çalışma başına 51 saniye, ancak i5-5200U dizüstü bilgisayarımda sadece .7 saniye sürüyor. Maksimum 5 saniyenin altında gelirken dizüstü bilgisayarda gerekli olan belirsizliği sağlar, böylece geçer. Görünüşe göre, PowerShell'in zamanlayıcısı birçok çekirdek ve kısa görevle iyi oynamıyor.
Techrocket9

Ve i7 5960x'de 58 saniye sürüyor
Techrocket9

Hm ... i5-6300U dizüstü bilgisayarda 74 saniye. Windows 10 veya PowerShell 5.1 ile ilgili bir sorun olabilir, çünkü i5-5200U, Win10'u çalıştırmayan test edilenler arasında tek makine (8.1 çalışıyor).
Techrocket9

@ Techrocket9 tuhaf, Win10, PS 5.1 üzerinde test yapıyordum. Yine de İMKB'de.
Briantist

2

Linux'ta GCC, 47 bayt

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

Bu bana her seferinde gcc(bayraksız) 4.9.2 sürümü ile derlenmiş farklı sonuçlar verdi . Özellikle, 64 bit Debian 8.6'daydım (çekirdek sürüm 3.16.31).

açıklama

Eğer fork()döner (çocuk işlemi), sıfır değerinin ibasılır ve nedeniyle çevrim durumu, yanlış printfsıfırdan büyük bir değer olması döndürür. Üst işlemde döngü koşulu sadece i--.


Bash cevabı ile aynı. Windows üzerinde deterministik, ancak Linux'a geçer (bu durumda Debian).
Techrocket9
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.