Визначте недетермінізм, що виникає в результаті планувальника потоків ОС


10

Як ми всі знаємо, сучасні операційні системи мають планувальники потоків, які можуть вибирати різні замовлення для планування ваших потоків на основі внутрішньої логіки, до якої ваш код не прихований. Зазвичай ви проектуєте свій багатопотоковий код, щоб переконатися, що цей недетермінізм, накладений на вас, не має значущого впливу на ваш результат.

Мета тут - протилежна. Створіть програму, яка друкує цілі числа в інтервалі [0,99], але в порядку, який буде змінюватися від запуску до запуску завдяки планувальнику потоків ОС.

Ви повинні досягти "достатнього недетермінізму", визначеного як:

У 10 послідовних наборах з 10 випробувань ваша програма повинна створити щонайменше 9 унікальних перестановок у межах кожного випробування. Ви можете мати достатню кількість невдалих наборів випробувань з будь-якої сторони послідовних 10, які досягли успіху.

Або, простіше кажучи, вам потрібно 100 запусків вашої програми, де кожен блок з 10 запусків має щонайбільше два запуски, які виводять те саме.

Тож час від часу обмінюванням 98 та 99 це не скоротить.

Це , тому відповідь, в якій використовується найменше байт, виграє.

Хвилини

  • Напишіть свій вихід у stdout, один запис у рядку
  • Якщо ви маніпулюєте формат, маючи два перемежуваних символи, що записують у stdout (навіть зрідка), що призводить до таких речей, як трицифрові числа чи порожні рядки, результат недійсний
  • Єдиним винятком із вищезазначеного правила є те, що ви можете випустити один порожній рядок після друку останнього необхідного номера (бажано)
  • Якщо ви коли-небудь пропускаєте чи дублюєте будь-які необхідні значення, результат недійсний
  • Вашій програмі не потрібно бути недетермінованою на одноядерному процесорі (хоча кудо, якщо є)
  • Ваша програма може використовувати зелені нитки / волокна, які фактично не керуються ядром ОС, якщо вона все ще відповідає іншим вимогам завдання, і система нарізки є частиною вашої мови або стандартної бібліотеки для вашої мови
  • Час виконання вашої програми повинен бути надійно меншим за 5 секунд на сучасному процесорі
  • Ви не можете вказувати зміни в середовищі, які відбуваються поза вашою програмою, наприклад, очікування чи зміни налаштувань; Ваша програма повинна проходити 100-кратну передачу назад до спини або з годиною між кожним пробігом або 100 разів паралельно (це, мабуть, допоможе насправді ...)
  • Ви можете використовувати такий копроцесор, як GPU або Xeon Phi, і власний внутрішній механізм планування для виконання завдань. Правила застосовуються до цього так само, як і до зелених ниток.
  • Сміливо провокуйте планувальника всіма способами сну, врожаїв та іншими хитрощами, якщо ви дотримуєтесь правил, зазначених у цій публікації.

Заборонені операції

Єдине джерело недетермінізму, до якого ви можете дозволитись, - це коли планувальник планує запускати ваші потоки. Наступний список не є вичерпним, призначений лише для того, щоб навести приклади речей, які вам заборонено робити, як вони визнають інші джерела недетермінізму.

  • Прямий або опосередкований доступ до будь-якого типу PRNG або апаратних можливостей RNG (якщо це не є невід'ємною частиною планувальника).
  • Читання будь-якого типу введення (системний час, файлова система, мережа тощо)
  • Читання ідентифікаторів потоку або ідентифікаторів процесів
  • Настроювання планувальника ОС; ви повинні використовувати стандартний планувальник ОС з основної ОС
  • Настроювання планувальника зелених ниток / волокон також заборонено. Це означає, що якщо ви пишете мову для цього завдання, ви повинні використовувати потоки ОС.

Перевірка відповідей

Переважно відповідь буде працювати у всіх звичайних ОС та сучасних процесорах, причому кудос присвоюється пропорційно широті підтримки. Однак це не є вимогою виклику. Як мінімум, відповідь повинна підтримувати один сучасний SMP-процесор та сучасну ОС. Я перевіряю провідні відповіді в мірі наявності мого обладнання.

  • Якщо ваш запис не дасть необхідного виводу для i7 5960x під керуванням Windows 10 v1607 x64, вкажіть необхідне середовище
  • Якщо я щось можу легко відтворити за допомогою VMWare Workstation, надайте точні характеристики ОС та VM
  • Якщо його не можна створити ні в одному з цих умов, запишіть одночасний знімок екрана тесту, як описано в розділі заголовка, та ручну відеозапис вашого екрана за допомогою взаємодії миші та клавіатури (або будь-якої схеми управління вашої нестандартної обчислення. пристрій використовує) чітко видно і розміщуйте обидва відео разом із вашою відповіддю та додайте пояснення, чому це працює
  • Крім того, знайдіть поважного давнього користувача (хто не ви) з відповідним обладнанням, щоб відтворити результат і поручити за вас
  • Якщо ваш запис є екзотичною мовою програмування, типовий розробник не буде налаштований на компіляцію / jit / interpret, надайте інструкції з налаштування
  • Якщо запис залежить від конкретної версії інтерпретатора JVM / Python / іншого, вкажіть, яку саме
  • Якщо на те, щоб отримати 10 успішних послідовних наборів випробувань на моєму тестуванні, потрібно більше 10 хвилин, щоб не вдалося (тому не дозволяйте умові успіху бути виродком, особливо якщо ви знаходитесь біля верхнього час виконання)

4
-1 для "Якщо мені нудно ....". Я б сказав, точно уточніть, скільки часу це може зайняти.
Rɪᴋᴇʀ

@EasterlyIrk Він також говорить "надійно за п'ять секунд на сучасному процесорі"
Павло

@Pavel, це не те, про що я маю на увазі. 10 успішних випробувань не пов'язані з 5 секундами.
Rɪᴋᴇʀ

@EasterlyIrk Ярмарок, зараз 10 хвилин.
Techrocket9

@ Techrocket9 круто, скасовано скасування.
Rɪᴋᴇʀ

Відповіді:


4

Perl 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 

Інструкції з налаштування:

Я пройшов тест із оновленим Rakudo Perl 6 на 64-бітовому Linux, хоча, мабуть, він буде працювати на інших платформах.

На сторінці завантаження Rakudo є інструкція з налаштування. Я склав мою з git так:

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

Спробуйте в Інтернеті:

Або просто протестуйте його в Інтернеті, скориставшись цим посиланням Try it Online, наданим @ b2gills. Я перевіряв кілька запусків і отримував інше замовлення кожен раз, але не мав терпіння виконати його 100 разів через Інтернет-інтерфейс.



Підтверджено для Windows 10 x64 на i7 5960x з версією Rakudo Perl 2016.11
Techrocket9

4

bash, 32 28 байт

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

Я пробіг це 100 разів і отримав 100 різних результатів.

Редагувати: Збережено 4 байти завдяки @DigitalTrauma.


Ти побив мене до цього. Насправді мій трохи коротший for i in {0..99};{ echo $i&}, але ви опублікували перший - ви можете взяти його :)
Digital Trauma

Ось як ви можете перевірити його в TIO. Це робить 10 запусків сценарію, фіксуючи вихід з кожного запуску, md5ing виведення з кожного запуску. Ми можемо бачити, що md5s кожен раз відрізняються. Md5s відсортовані, щоб зробити потенційні дублікати очевидними.
Цифрова травма

@DigitalTrauma Недокументоване, але приємно!
Ніл

1
Так - для цього є порада .
Цифрова травма

Цікаво, що це не вдається досягти "достатнього недетермінізму", коли він працює в офіційних системах Microsoft на базі вікон на E5-2699 v4, однак він працює в робочій станції VEL RHEL з 4 ядрами на одній машині, так що він проходить.
Techrocket9

2

PowerShell , 54 46 44 39 байт

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

Робочі процеси PowerShell не підтримуються в TIO, тому ви не можете спробувати його там. Потрібно чудово працювати на вашій машині Windows 10 :)

Визначає функцію, pяка виводить список номерів при виклику.

Хронометраж

Один пробіг надійно працює на моїй машині приблизно за 600 мс. 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 секунда за пробіг, але лише 7,7 секунди на моєму ноутбуці i5-5200U. Він досягає необхідного ступеня недетермінізму на ноутбуці, вступаючи під максимум 5 секунд, тому він проходить. Мабуть, планувальник PowerShell не дуже добре поєднується з багатьма ядрами та короткими завданнями.
Techrocket9

І це займає 58 секунд на i7 5960x
Techrocket9

Хм ... 74 секунди на ноутбуці i5-6300U. Можливо, це проблема з Windows 10 або PowerShell 5.1, оскільки i5-5200U є єдиною машиною серед перевірених, на якій не працює Win10 (він працює під управлінням 8.1).
Techrocket9

@ Techrocket9 дивно, я тестував на Win10, PS 5.1. В ISE, хоча.
британіст

2

GCC на Linux, 47 байт

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

Це дало мені різні результати кожен раз, будучи складеними gcc (без прапорців) версії 4.9.2. Зокрема, я був на 64-розрядному Debian 8.6 (версія ядра 3.16.31).

Пояснення

Якщо fork()повертається нуль (дочірній процес), значення " iдрукується", а умова циклу - хибна, тому що printfповерне значення, що перевищує нуль. У батьківському процесі умова циклу справедлива i--.


Те саме, що баш відповідь. Визначається у Windows, але передається на Linux (у цьому випадку Debian).
Techrocket9
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.