OS 스레드 스케줄러로 인한 비결 정성 노출


10

우리 모두 알다시피, 현대 운영 체제에는 스레드 스케줄러가있어 코드가 특권이없는 내부 논리를 기반으로 스레드를 예약하기 위해 다른 순서를 선택할 수 있습니다. 일반적으로 다중 스레드 코드를 설계하여 사용자에게 부과 된 비결정론이 출력에 의미있는 영향을 미치지 않도록합니다.

여기서 목표는 반대입니다. [0,99] 간격으로 정수를 인쇄하지만 OS 스레드 스케줄러로 인해 실행마다 다른 순서로 프로그램을 생성하십시오.

다음과 같이 정의 된 "충분한 비결정론"을 달성해야합니다.

순차적으로 10 번의 10 번의 시행에서 프로그램은 각 시행 내에서 최소 9 개의 순열을 생성해야합니다. 성공한 연속 10 개 중 어느쪽에 든 합당한 수의 실패한 시도 세트가있을 수 있습니다.

또는 달리 말하면, 10 개의 런의 각 블록에는 최대 2 개의 런이있어 동일한 것을 출력하는 프로그램의 100 개의 런이 필요합니다.

따라서 때때로 98과 99를 교체해도 문제가 해결되지 않습니다.

이것은 이므로 가장 적은 바이트를 사용하는 답이 이깁니다.

사소한 점

  • 출력을 한 줄에 하나씩 stdout에 기록하십시오.
  • 두 개의 스레드가 stdout에 문자 쓰기를 인터리브하여 (때로는) 3 자리 숫자 또는 빈 줄과 같은 결과로 형식을 엉망으로 만들면 결과가 유효하지 않습니다
  • 위의 규칙에 대한 유일한 예외는 마지막으로 필요한 숫자를 인쇄 한 후 빈 줄을 하나 만들 수 있다는 것입니다 (환영합니다).
  • 필요한 값을 놓치거나 복제하면 결과가 유효하지 않습니다
  • 단일 코어 프로세서에서 프로그램이 비 결정적 일 필요 는 없습니다 (만약 괜찮다면)
  • 프로그램은 여전히 ​​챌린지의 다른 요구 사항을 충족하고 스레딩 시스템이 언어의 일부이거나 언어의 표준 라이브러리 인 경우 OS 커널에서 실제로 관리하지 않는 녹색 스레드 / 섬유를 사용할 수 있습니다.
  • 최신 프로세서에서 프로그램의 런타임은 5 초 미만이어야합니다.
  • 대기 또는 설정 변경과 같이 프로그램 외부에서 발생하는 환경 변경은 지정할 수 없습니다. 프로그램은 100ish 시간을 다시 연속으로 실행하거나 각 실행 사이에 1 시간 또는 100ish 시간을 병렬로 실행해야합니다.
  • GPU 또는 Xeon Phi와 같은 보조 프로세서 및 작업을위한 자체 내부 스케줄링 메커니즘을 사용할 수 있습니다. 규칙은 녹색 스레드에 적용되는 것과 동일한 방식으로 적용됩니다.
  • 이 게시물에 지정된 규칙을 준수하는 한 모든 수면, 수율 및 기타 트릭으로 스케줄러를 자극하십시오.

금지 된 운영

스케줄러가 스레드 실행을 스케줄 할 때 비결 정성 소스 만 사용할 수 있습니다. 다음 목록은 전체가 아니며 다른 비결정론 적 출처를 인정하므로 귀하가 할 수없는 것들의 예를 제공하기위한 것입니다.

  • 모든 종류의 PRNG 또는 하드웨어 RNG 기능에 직접 또는 간접적으로 액세스 (스케줄러의 고유 한 부분이 아닌 경우).
  • 모든 종류의 입력 (시스템 시간, 파일 시스템, 네트워크 등)으로 읽기
  • 스레드 ID 또는 프로세스 ID 읽기
  • OS 스케줄러 사용자 정의 주류 OS에서 표준 OS 스케줄러를 사용해야합니다
  • 녹색 실 / 섬유 스케줄러를 사용자 정의하는 것도 금지됩니다. 즉,이 과제에 대한 언어를 작성 하려면 OS 스레드 사용해야합니다.

답변 검증

바람직하게는 대답은 폭 넓은 지원에 비례하여 칭찬을받는 모든 일반적인 OS 및 최신 프로세서에서 작동합니다. 그러나 이것은 도전의 요구 사항이 아닙니다. 최소한 하나의 최신 SMP 프로세서와 최신 OS를 지원해야합니다. 하드웨어 가용성의 범위까지 최고의 답변을 테스트합니다.

  • 항목이 Windows 10 v1607 x64를 실행하는 i7 5960x에서 필요한 출력을 생성하지 않으면 필요한 환경을 지정하십시오.
  • VMWare Workstation으로 쉽게 재현 할 수있는 경우 정확한 OS 및 VM 사양을 제공하십시오.
  • 이러한 조건 중 하나에서 생성 할 수없는 경우, 헤더 섹션에 설명 된대로 테스트의 동시 화면 캡처와 마우스 및 키보드 상호 작용 (또는 비표준 계산 제어 방식을 사용하여 화면의 핸드 헬드 비디오 녹화)을 기록하십시오. 기기 사용)를 명확하게 표시하고 답변과 함께 두 동영상을 게시하고 작동 이유에 대한 설명을 포함합니다.
  • 또는, 일치하는 하드웨어를 보유한 평판이 좋은 오랜 사용자 (귀하가 아닌)를 확보하여 결과를 재현하고 보증하십시오.
  • 항목이 이국적인 프로그래밍 언어로되어있어 일반적인 개발자가 컴파일 / 지트 / 통역하도록 설정되지 않은 경우 설정 지침을 제공하십시오.
  • 항목이 특정 버전의 JVM / Python 인터프리터 / 기타에 의존하는 경우 다음을 지정하십시오.
  • 내 테스트에서 10 번의 연속적인 시련 세트를 얻는 데 10 분 이상의 연속적인 실행이 실패하면 실패합니다 (특히 성공 조건이 이상한 경우가 아닙니다) 런타임 바운드)

4
"지루하면 ..."-1 시간이 얼마나 걸리는지 정확히 말하고 싶습니다.
Rɪᴋᴇʀ

@EasterlyIrk 또한 '현대 CPU에서 5 초 미만으로 안정적으로 작동합니다'
Pavel

@Pavel 그것은 내가 말하는 것이 아닙니다. 10 번의 성공적인 시험은 5 초와 관련이 없습니다.
Rɪᴋᴇʀ

@EasterlyIrk Fair 충분히, 이제 10 분입니다.
Techrocket9

@ Techrocket9 시원하고 downvote는 철회했다.
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 비트 Linux에서 최신 Rakudo Perl 6으로 테스트를 실행했지만 다른 플랫폼에서 작동한다고 생각합니다.

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"

온라인으로 사용해보십시오 :

또는 @ b2gills에서 제공하는 온라인 시험판 링크를 사용하여 온라인으로 테스트하십시오 . 나는 몇 번의 런을 확인하고 매번 다른 순서를 얻었지만 온라인 인터페이스를 통해 100 번 실행하는 인내심을 갖지 못했습니다.



Rakudo Perl 버전 2016.11이 설치된 i7 5960x의 Windows 10 x64에서 검증되었습니다.
Techrocket9

4

bash, 32 28 바이트

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

나는 이것을 100 번 실행하고 100 개의 다른 결과를 얻었습니다.

편집 : @DigitalTrauma 덕분에 4 바이트가 절약되었습니다.


당신은 나를 이겼습니다. 실제로 광산은 조금 짧지 for i in {0..99};{ echo $i&}만 먼저 게시했습니다
Digital Trauma

TIO에서 테스트 할 수 있는 방법은 다음과 같습니다 . 이 스크립트는 10 회의 실행을 수행하여 각 실행의 출력을 캡처하고 각 실행의 출력을 md5합니다. md5가 매번 다른 것을 볼 수 있습니다. md5는 잠재적 중복을 명백하게 나타 내기 위해 정렬됩니다.
디지털 외상

@DigitalTrauma 서류 미비이지만 멋진!
Neil

1
그렇습니다- 이것에 대한 이 있습니다.
디지털 외상

흥미롭게도, 이것은 E5-2699 v4에서 Microsoft의 공식 bash-on-windows에서 실행될 때 "충분히 비결정론 적"을 달성하지 못하지만 동일한 머신에 4 개의 코어가있는 RHEL Workstation VM에서 작동하므로 통과합니다.
Techrocket9

2

PowerShell , 54 46 44 39 바이트

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

PowerShell 워크 플로는 TIO에서 지원되지 않으므로 여기서 시도 할 수 없습니다. 그래도 Windows 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 초. i5-5200U는 Win10을 실행하지 않는 것으로 테스트 된 시스템 중 유일한 시스템 (8.1을 실행 중)이므로 Windows 10 또는 PowerShell 5.1에서 문제 일 수 있습니다.
Techrocket9

@ Techrocket9 이상합니다 .Win10, PS 5.1에서 테스트 중이었습니다. 그러나 ISE에서는.
briantist

2

Linux의 GCC, 47 바이트

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

이것은 gcc(플래그 없음) 버전 4.9.2 로 컴파일되어 매번 다른 결과를 얻었습니다 . 특히 64 비트 데비안 8.6 (커널 버전 3.16.31)을 사용하고있었습니다.

설명

경우 fork()반환 (자식 프로세스)는 0의 값을 i인쇄하고 있기 때문에 루프 조건이 거짓 printf0보다 값 이상을 반환합니다. 부모 프로세스에서 루프 조건은 단지 i--입니다.


bash 답변과 동일합니다. Windows에서는 결정 론적이지만 Linux에서는 통과합니다 (이 경우 Debian).
Techrocket9
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.