hotchpotch/wikipedia-multilingual-ir-pairs huggingface dataset:
GPFS 역사
베스타는 1994년경 PIOFS 파일 시스템으로 상용화되었으며, 1998년경 GPFS가 그 뒤를 이었다. 이전 파일 시스템과 새로운 파일 시스템의 주요 차이점은 GPFS가 Vesta/PIOFS에서 제공하는 특수화된 API를 표준 유닉스 API로 대체했다는 점이다. 고성능 병렬 I/O를 지원하는 모든 기능은 사용자에게 숨겨져 백그라운드에서 구현되었다. GPFS는 또한 관련 제품인 IBM 멀티미디어 서버(IBM Multi-Media Server) 및 IBM 비디오 충전기(IBM Video Charger)와 많은 구성 요소를 공유하며, 이 때문에 많은 GPFS 유틸리티가 접두사 mm—멀티미디어(multi-media)로 시작한다.:xi
2010년 IBM은 GPFS-SNC라는 기능을 포함한 GPFS 버전을 미리 선보였다. 여기서 SNC는 공유 없음 클러스터(Shared Nothing Cluster)를 의미한다. 이는 2012년 12월 GPFS 3.5와 함께 공식적으로 출시되었으며, 현재 FPO
 (파일 배치 최적화기)로 알려져 있다.
GPFS 아키텍처
이것은 클러스터 파일 시스템이다. 파일을 구성된 크기의 블록으로 나누고, 각 블록은 1메가바이트 미만이며, 여러 클러스터 노드에 분산된다.
이 시스템은 표준 블록 저장 볼륨에 데이터를 저장하지만, RAID 블록 저장 시스템과 매우 유사하게 중복성 및 병렬 접근을 위해 해당 볼륨을 가상화할 수 있는 내부 RAID 계층을 포함한다. 또한 상위 파일 수준에서 볼륨 간에 복제할 수 있는 기능도 있다.
아키텍처의 특징은 다음과 같다.
파티션 인식. 네트워크 오류로 인해 파일 시스템이 두 개 이상의 노드 그룹으로 분할될 수 있으며, 각 그룹은 해당 그룹 내의 노드만 볼 수 있다. 이는 하트비트 프로토콜을 통해 감지할 수 있으며, 파티션이 발생하면 파일 시스템은 형성된 가장 큰 파티션에서 계속 작동한다. 이는 파일 시스템의 점진적인 성능 저하를 제공한다. 일부 머신은 계속 작동한다.
GPFS 아키텍처
다른 기능으로는 고가용성, 이기종 클러스터에서의 사용 가능성, 재해 복구, 보안, DMAPI, HSM 및 ILM이 있다.
하둡의 HDFS 파일 시스템은 상품 하드웨어, 즉 RAID 디스크 및 스토리지 에어리어 네트워크(SAN)가 없는 데이터 센터에 유사하거나 더 많은 양의 데이터를 저장하도록 설계되었다.
GPFS 정보 수명 주기 관리
저장 풀은 파일 시스템 내에서 디스크를 그룹화할 수 있도록 한다. 관리자는 성능, 지역성 또는 신뢰성 특성을 기반으로 디스크를 그룹화하여 저장 계층을 만들 수 있다. 예를 들어, 한 풀은 고성능 파이버 채널 디스크일 수 있고 다른 풀은 더 경제적인 SATA 저장 장치일 수 있다.
파일셋(fileset)은 파일 시스템 이름 공간의 하위 트리이며, 이름 공간을 더 작고 관리하기 쉬운 단위로 분할하는 방법을 제공한다. 파일셋은 할당량을 설정하고 초기 데이터 배치 또는 데이터 마이그레이션을 제어하는 정책에 지정될 수 있는 관리 경계를 제공한다. 단일 파일셋의 데이터는 하나 이상의 저장 풀에 존재할 수 있다. 파일 데이터가 어디에 존재하고 어떻게 마이그레이션되는지는 사용자 정의 정책의 규칙 세트를 기반으로 한다.
GPFS 정보 수명 주기 관리
두 가지 유형의 사용자 정의 정책이 있다: 파일 배치 및 파일 관리. 파일 배치 정책은 파일이 생성될 때 파일 데이터를 적절한 저장 풀로 보낸다. 파일 배치 규칙은 파일 이름, 사용자 이름 또는 파일셋과 같은 속성으로 선택된다. 파일 관리 정책은 파일 데이터를 이동하거나 복제하거나 파일을 삭제할 수 있도록 한다. 파일 관리 정책은 디렉터리 구조에서 파일의 위치를 변경하지 않고 데이터를 한 풀에서 다른 풀로 이동하는 데 사용될 수 있다. 파일 관리 정책은 마지막 접근 시간, 경로 이름 또는 파일 크기와 같은 파일 속성으로 결정된다.
정책 처리 엔진은 확장 가능하며 여러 노드에서 동시에 실행될 수 있다. 이를 통해 관리 정책을 수십억 개의 파일이 있는 단일 파일 시스템에 적용하고 몇 시간 내에 완료할 수 있다.
동래읍성역사축제
소개
1995년 제1회 충렬제를 시작으로 31년 동안 이어져온 부산광역시 동래구의 대표적인 역사교육형 체험축제로, 올해는 '동래성 사람들, 역사와 미래를 잇다!'라는 새로운 슬로건으로 개최된다. 2025년 제31회 동래읍성역사축제는 새로운 시작을 위해 대표프로그램인 동래성전투재현 실경뮤지컬을 더욱 업그레이드하여 미디어아트와 접목한 퍼포먼스를 제공할 예정이며, 야외방탈출, 몰입형영상체험관 등 새로운 콘텐츠를 추가하여 10월 24일부터 10월 26일까지 5개 분야 51개 프로그램으로 구성될 예정이다.
동래성 전투재현 뮤지컬
[제1장 : 평 화] 평화로운 동래읍성
평화로운 동래의 모습
논밭을 가로 있는 농민들의 모습
풍물패들의 흥겨운 가락
노인들과 아이들의 행복한 모습
[제2장 : 잔 치] 송상현 부사의 부임잔치
송상현부사의 부임소식에 환호하는 백성
부사의 부임을 축하하기 위한 잔치의 준비
배우와 관객들이 어우러진 신나는 춤판
[제3장 : 침 략] 전령으로부터 전해진 왜군침략소식
전령으로부터 전쟁소식이 들려온다
혼란에 빠진 백성들
나라를 지킬지 도망을 갈지에 대한 의견이 분분하다.
동래읍성역사축제
[제4장 : 맹 세] 나라를 지키기 위한 조건없는 맹세
송상현 부사는 나라를 지키는 이유에 대해 노래한다.
송상현 부사에게 동화된 백성들은 나라에 대한 조건없는 맹세를 다짐한다.
임진년, 첫 전투지 ‘부산진성’이 함락되었다는 소식을 전해들은 경상좌병사(현재의 육군 부대장) 이각(李珏)은 송상현(宋象賢) 동래부사에게 모든 것을 떠넘기고 성문을 열고 도망갔다. 그래서 동래읍성은 고립무원의 상태에서 적의 대군을 맞아 격전을 벌일 수 밖에 없었다.
1592년 4월 14일 오후 왜군은 3개 부대로 나누어 “싸우려면 싸우고, 싸우지 않으려면 길을 빌려 달라.(戰則戰矣 不戰則假我道)”라는 문구가 새겨진 나무 팻말을 세우고 동래읍성 남문 앞으로 다가왔다. 이에 송 부사는 “싸워서 죽기는 쉬워도 길을 빌려주기는 어렵다.(戰死易假道難)”라는 글을 나무판자에 적어 적진에 던졌다.
동래읍성역사축제
15일 아침, 마침내 하늘을 가르는 왜군의 조총 소리와 함께 치열한 전투가 시작되었다. 공격 중심지는 남문이었다. 조선군은 남문을 중심으로 집결해 항전했으나, 시간이 갈수록 불리해지기 시작했다.
결국 왜군이 상대적으로 방어가 허술한 동북쪽 경사진 성벽을 무너뜨리고 성 안으로 밀어닥치자 성 안에서는 백병전(白兵戰)이 벌어졌다.
백성들은 낫, 괭이, 막대기 등을 들고 죽기로 싸웠지만 왜군의 병력에는 중과부적으로 동래읍성은 고을 백성들의 비명 소리가 넘쳐났다.
송 부사는 전세가 기운 것을 알고 갑옷 위에 관복을 입고 임금이 계신 북쪽으로 네 번 절한 뒤 부모님에게 올릴 글을 부채에 쓴 후 장렬히 최후를 맞이한다.
孤城月暈(고성월운) 외로운 성은 달무리처럼 포위되었는데
列鎭高枕(열진고침) 여러 다른 진영에서는 도와줄 기척이 없습니다.
君臣義重(군신의중) 임금과 신하의 의리가 무거우니
父子恩輕(부자은경) 부모와 자식의 은정을 가벼이 하오리다.
시내버스
시내버스로 오실 때
(명륜초등학교에서 하차) 110-1,110, 51, 49
(동래우체국에서 하차) 179, 50
동래읍성역사축제
지하철에서 마을버스환승
마을버스 6번 : 동래역(1호선 하차) → 복천박물관(행사장)
마을버스 7번 : 온천장역(1호선 하차) →동래문화회관(행사장)
자가용
남해고속도로 : 서부산 TG→동서고가도로→진양램프→하마정교차로→ 온천교사거리→동래문화원(행사장)
경부고속도로 : 구서 IC→중앙대로→오시게로→온천장입구→동래문화원(행사장)
축제셔틀버스
1코스 : 도시철도 1호선 동래역(3번출구) ↔ 축제장(동래문화회관 소극장 앞) ▸ 10분 간격
2코스 : 도시철도 4호선 명장역(3번 출구) → 축제장(복천박물관) → 명장역(3번 출구) → 온천천 카페거리(샤브향 온천천점)(하차)
2025.10.24.(금) 16:00~21:00
2025.10.25.(토)~10.26.(일) 10:00~21:00
동래구청 홈페이지 https://www.dongnae.go.kr/festival/index.dongnae
Zswap
zswap은 가상 메모리 압축의 한 형태로, 스와프된 페이지를 위한 압축된 쓰기 저장(write-back) 캐시를 제공하는 리눅스 커널 기능이다. 메모리 페이지가 스와프 아웃될 때 스와프 장치로 이동하는 대신, zswap은 해당 페이지를 압축한 다음 시스템 RAM에 동적으로 할당된 메모리 풀에 저장한다. 실제 스와프 장치로의 쓰기 저장은 지연되거나 완전히 회피되어, 스와핑이 필요한 리눅스 시스템의 I/O를 크게 줄인다. 대신 압축을 수행하기 위해 추가적인 CPU 사이클이 필요하다.
I/O 감소의 결과로, zswap은 임베디드 장치, 넷북 및 유사한 저가형 하드웨어 장치를 포함한 다양한 플래시 메모리 기반 저장 장치를 사용하는 장치뿐만 아니라, SSD를 저장 장치로 사용하는 다른 장치에도 이점을 제공한다. 플래시 메모리는 쓰기 증폭으로 인해 수명이 제한적이므로, 이를 스와프 공간으로 사용하는 것을 피하면 빠르게 마모되는 것을 방지할 수 있다.
Zswap 내부 동작
zswap은 스와프 공간으로 사용될 수 있는 다양한 유형의 스토리지를 추상화하는 리눅스 커널 메커니즘인 frontswap이 제공하는 API를 사용하여 리눅스 커널의 나머지 가상 메모리 서브시스템에 통합된다. 결과적으로 zswap은 내부적으로 유사-RAM 장치로 보이는 것을 제공하여 frontswap의 백엔드 드라이버로 작동한다. 즉, frontswap API는 zswap이 메모리 페이지가 스와프 아웃될 때 이를 가로채고, 이미 스와프된 페이지에 대한 페이지 부재를 가로챌 수 있게 한다. 이 두 경로에 대한 접근은 zswap이 스와프된 페이지를 위한 압축된 쓰기 저장 캐시 역할을 할 수 있도록 한다.
Zswap 내부 동작
내부적으로 zswap은 리눅스 커널의 크립토 API가 제공하는 압축 적재 가능 커널 모듈을 사용한다. 이를 통해 예를 들어, 리눅스 커널이 지원하는 모든 하드웨어 압축 가속기를 사용하여 주 CPU에서 압축 작업을 오프로드할 수 있다. 원하는 압축 모듈 선택은 커널 부트 매개변수 zswap.compressor 값을 통해 부팅 시 동적으로 수행할 수 있다. 지정하지 않으면 Lempel–Ziv–Oberhumer (LZO) 압축이 선택된다. 리눅스 커널 버전 3.13부터는 커널 부트 매개변수 zswap.enabled에 값 1을 지정하여 zswap을 명시적으로 활성화해야 한다. 그러나 CONFIG_ZSWAP_DEFAULT_ON=y로 커널을 구성할 때 기본적으로 활성화되거나, sysfs 인터페이스를 통해 언제든지 활성화할 수 있다.
echo 1 > /sys/module/zswap/parameters/enabled
Zswap 내부 동작
zswap이 사용하는 메모리 풀의 최대 크기는 max_pool_percent sysfs 매개변수를 통해 구성할 수 있다. 이 매개변수는 풀이 차지할 수 있는 전체 시스템 RAM의 최대 비율을 지정한다. 메모리 풀은 구성된 최대 크기로 미리 할당되지 않고, 필요에 따라 증가하고 축소된다. 스와핑 결과로 구성된 최대 풀 크기에 도달하거나 메모리 부족 조건으로 인해 풀을 확장할 수 없을 때, 스와프된 페이지는 캐시 축출 기반으로 LRU 방식으로 메모리 풀에서 스와프 장치로 축출된다. 이 접근 방식은 zswap을 진정한 스와프 캐시로 만든다. 캐시가 가득 차면 가장 오래된 캐시된 페이지가 스와프 장치로 축출되어 새로운 스와프 페이지가 압축되고 캐시될 공간을 만든다.
zbud은 zswap이 압축된 페이지를 저장하기 위해 내부적으로 사용하는 특수 목적의 메모리 할당자이다. 이는 오라클의 zcache에서 사용되는 zbud 할당자를 재작성하여 구현되었다. zcache는 리눅스 커널을 위한 또 다른 가상 메모리 압축 구현이다. 내부적으로 zbud는 물리적 메모리 페이지당 최대 두 개의 압축된 페이지("버디", 따라서 할당자 이름)를 저장하여, 해제된 공간의 쉬운 통합 및 재사용으로 인한 이점과 낮은 메모리 활용 가능성으로 인한 단점을 모두 가져온다. 그러나 설계 결과로 zbud는 원래 압축되지 않은 페이지가 차지했을 것보다 더 많은 메모리 공간을 할당할 수 없다.
Zswap 역사
zswap과 zbud는 모두 세스 제닝스(Seth Jennings)가 만들었다. 첫 공개 발표는 2012년 12월이었고, 개발은 2013년 5월까지 계속되어 코드베이스가 실험적 커널 기능 상태였음에도 불구하고 성숙 단계에 도달했다.
zswap (zbud와 함께)은 2013년 9월 2일에 출시된 커널 버전 3.11에서 리눅스 커널 메인라인에 병합되었다.
2014년 6월 8일에 출시된 리눅스 커널 버전 3.15부터 zswap은 여러 스와프 장치를 제대로 지원한다.
2024년 3월 11일에 출시된 리눅스 커널 버전 6.8부터 zswap은 특정 cgroup에 대한 쓰기 저장을 비활성화하는 것을 지원한다.
Zswap 대안
zswap의 대안 중 하나는 zram으로, 리눅스 커널에 유사하지만 여전히 다른 "RAM에 압축된 페이지 스와프" 메커니즘을 제공한다.
주요 차이점은 zram이 데이터를 저장하기 위해 RAM을 사용하여 압축된 블록 장치를 제공한다는 점이다. 이는 일반적이고 별개의 스와프 장치 역할을 한다.
이에 비해 zswap은 스와프 장치를 위한 RAM 기반 캐시 역할을 한다. 이는 zswap에 덜 사용된 스와프 페이지에 대한 캐시 축출 메커니즘을 제공하는데, zram은 커널 버전 4.14에서 CONFIG_ZRAM_WRITEBACK이 도입되기 전까지는 이 기능이 없었다. 하지만 설계상 zswap을 사용하려면 이미 존재하는 스와프 장치가 적어도 하나 필요하다.
ISACA
ISACA(정식 명칭: 정보 시스템 감사 및 통제 협회, Information Systems Audit and Control Association)는 IT 거버넌스에 중점을 둔 국제 전문 협회이다.
ISACA는 현재 8개의 인증 프로그램과 기타 마이크로 인증을 제공한다.
ISACA 역사
ISACA는 1967년 미국에서 컴퓨터 시스템의 감사 통제 업무를 수행하는 일단의 사람들이 조직 운영에 대해 점점 더 비판적인 입장을 취하면서 시작되었다. 그들은 이 분야에서 정보와 지침을 제공할 중앙 집중식 자료원의 필요성을 인식했다. 1969년, (나중에) 더글러스 에어크래프트의 직원이었던 스튜어트 타이르나우어(Stuart Tyrnauer)는 이 그룹을 EDP 감사 협회(EDPAA)로 통합했다. 타이르나우어는 처음 3년 동안 이 기구의 창립 회장을 역임했다. 1976년 이 협회는 정보기술 거버넌스 및 통제 분야에 대한 지식과 가치를 확대하기 위한 대규모 연구 노력을 수행하기 위해 교육 재단을 설립했다.
이 협회는 1994년에 정보 시스템 감사 및 통제 협회로 명칭을 변경했다.
2008년 기준으로 이 조직은 긴 이름을 버리고 자신을 ISACA로 브랜딩했다.
2016년 3월, ISACA는 능력 성숙도 통합 모델을 개발한 CMMI 연구소를 인수했다.
2020년 1월, ISACA는 새로운 로고를 도입하며 외관과 디지털 존재를 업데이트하고 새로 단장했다.
ISACA 현재 상태
ISACA는 현재 180개 이상의 국가에서 185,000명 이상의 회원(ISACA 인증을 보유한 회원 및 전문가)에게 서비스를 제공하고 있다. 회원의 직함은 IS 감사자, 컨설턴트, 교육자, IS 보안 전문가, 규제 기관, 최고 정보 책임자, 최고 정보 보안 책임자 및 내부감사원 등이다. 그들은 거의 모든 산업 분야에서 일한다. 180개국 이상에 225개 이상의 지부가 설립된 ISACA 지부 네트워크가 있다. 지부는 교육, 자원 공유, 옹호, 네트워킹 및 기타 혜택을 제공한다.
ISACA 주요 발행물
통찰력 및 전문 지식
감사 프로그램 및 도구
출판물 - 감사 및 보증, 신흥 기술, 거버넌스, 정보 보안, 정보 기술, 개인 정보 보호, 위험에 대한 200개 이상의 전문 출판물 및 지침. 일부 주제는 다음과 같다.
인공지능
블록체인
공인 정보 시스템 감사원® (CISA®)CISA,AAIA,CISM,CRISC,CDPSE,CGEIT,CCOA,CSX-P 및 여러 자격증 과정 시험 준비 가이드
클라우드 컴퓨팅
COBIT
규정 준수
사이버 보안
데이터 거버넌스
데이터 과학
사물 인터넷
네트워크 인프라
소프트웨어 개발
위협 및 통제
공급업체 관리
젊은 전문가
ISACA 인증
ISACA의 첫 번째 사이버 보안 인증인 CSX-P는 2015년 여름에 도입되었다. 이는 개인이 실제 문제와 함께 실제 환경에서 작업해야만 인증을 얻을 수 있는 몇 안 되는 인증 중 하나이다. 특히, 이 시험은 응시자를 실제 사건이 발생하고 있는 라이브 네트워크에 배치한다. 사건에 대응하고 문제를 해결하려는 학생의 노력은 부여되는 점수의 유형으로 이어진다.
Readahead
readahead(리드어헤드)는 리눅스 커널의 시스템 호출로, 파일 내용을 버퍼 캐시에 로드한다. 이는 파일을 프리페칭하여 나중에 접근할 때 내용이 하드 디스크 드라이브 (HDD) 대신 주 기억 장치 (RAM)에서 읽혀 파일 접근 지연 시간을 훨씬 낮춘다.
많은 리눅스 배포판은 일반적으로 사용되는 파일 목록에 readahead를 사용하여 부팅 속도를 높인다. 이러한 설정에서 커널이 profile 부트 파라미터로 부팅되면, 부팅 중 모든 파일 접근을 기록하고 나중 부팅 시퀀스에서 읽을 새 파일 목록을 작성한다. 이는 기본 readahead 목록에 포함되지 않은 추가 설치된 서비스가 더 빨리 시작되도록 할 것이다.
Systemd를 사용하는 리눅스 배포판에서는 (부팅 시퀀스의 일부로) readahead 바이너리가 systemd-readahead로 대체되었다. 그러나 systemd 버전 217에서 readahead 지원이 제거되었으며, 유지 관리되지 않고 예상 성능 이점을 제공할 수 없다고 설명되었다.
특정 실험적인 페이지 수준 프리페칭 시스템이 성능을 더욱 향상시키기 위해 개발되었다.
브레인 퍽 스케줄러
브레인 퍽 스케줄러(Brain Fuck Scheduler, BFS)는 2009년 8월 리눅스 커널용으로 설계된 프로세스 스케줄러로, 가장 빠른 적격 가상 마감일 우선 스케줄링 (EEVDF)을 기반으로 하며, 컴플리틀리 페어 스케줄러 (CFS) 및 O(1) 스케줄러의 대안으로 개발되었다. BFS는 콘 콜리바스가 만들었다.
BFS의 목표는 다른 스케줄러와 비교하여, 특정 유형의 컴퓨테이션 작업 부하에 대한 성능을 맞추기 위해 휴리스틱 이론 조정이나 매개변수 튜닝이 필요 없는 더 간단한 알고리즘을 가진 스케줄러를 제공하는 것이다. 콜리바스는 이러한 튜닝 매개변수가 일반 사용자가 이해하기 어렵다고 주장했으며, 특히 여러 매개변수 간의 상호작용 측면에서 더욱 그러하다고 했다. 또한 이러한 튜닝 매개변수를 사용하면 특정 대상 컴퓨테이션 유형에서 성능이 향상될 수 있지만, 일반적인 경우에는 성능이 저하될 수 있다고 주장했다. BFS는 16개 미만의 CPU 코어를 가진 리눅스 데스크톱 컴퓨터에서 응답성을 향상시키는 것으로 보고되었다.
브레인 퍽 스케줄러
도입 직후, 새로운 스케줄러는 리눅스 커뮤니티에서 슬래시닷에 보도되었으며, 리눅스 매거진과 리눅스 프로 매거진에 리뷰가 실리면서 큰 화제가 되었다. 성능과 응답성이 향상되었다는 다양한 평가가 있었지만, 콘 콜리바스는 BFS를 메인라인 커널에 통합할 의도가 없었다.
"브레인 퍽 스케줄러"라는 이름은 의도적으로 도발적인데, 당시 기존 리눅스 프로세스 스케줄러의 복잡성에 대한 좌절감을 표현하기 위해 창시자 콘 콜리바스가 선택했다. 콜리바스는 컴플리틀리 페어 스케줄러 (CFS)와 같은 다른 스케줄러에서 튜닝 가능한 매개변수와 휴리스틱 기반 설계가 확산되면서 비전문가가 이해하거나 최적화하기 어렵다는 점을 강조하고자 했다. 이와 대조적으로 BFS는 사용자 수준의 구성 없이 데스크톱 상호작용성과 응답성 향상을 목표로 단순성과 예측 가능성을 염두에 두고 설계되었다.
브레인 퍽 스케줄러 이론적 설계 및 효율성
2009년 BFS가 도입되었고, 원래 이중 연결 리스트 자료 구조를 사용했지만, 이 자료 구조는 선입 선출 (FIFO) 큐처럼 취급된다. 작업 삽입은 이다.:ln 119–120 다음 작업을 실행하기 위한 작업 검색은 최악의 경우 이다.:ln 209 모든 CPU가 사용하는 단일 전역 실행 큐를 사용한다. 스케줄링 우선순위가 높은 작업이 먼저 실행된다.:ln 4146–4161 실시간 및 등시성 우선순위 클래스를 제외한 모든 정책에서 작업은 가상 마감일 공식에 따라 정렬(또는 배포)되고 선택된다.
브레인 퍽 스케줄러 이론적 설계 및 효율성
실행 동작은 라운드 로빈 스케줄링의 가중 변형이며, 특히 등시성 정책 미만에서 작업이 동일한 우선순위를 가질 때 더욱 그렇다.:ln 1193–1195, 334–335 사용자 튜닝 가능한 라운드 로빈 간격(타임 슬라이스)은 기본적으로 6밀리초로, 이는 사람이 감지할 수 없는 최소한의 지터로 선택되었다.:ln 306 콜리바스는 6ms 미만은 무의미하고, 라운드 로빈 타임슬라이스에 대해 300ms 이상은 처리량 측면에서 무익하다고 주장했다.:ln 314–320 이 중요한 튜닝 가능 값은 처리량과 지연 시간 사이의 절충안으로 라운드 로빈 스케줄러를 맞춤 설정할 수 있다.:ln 229–320 모든 작업은 실시간 FIFO를 제외하고 동일한 타임 슬라이스를 받는데, 이는 무한한 타임 슬라이스를 가진다고 가정된다.:ln 1646, 1212–1218, 4062, 3910
브레인 퍽 스케줄러 이론적 설계 및 효율성
콜리바스는 RDSL 스케줄러에서 사용했던 CPU당 다중 실행 큐(라운드 로빈:par. 3) 우선순위 배열 대신 이중 연결 리스트 단일 실행 큐를 선택한 이유를 설명했다. 이는 다중 CPU 시나리오에서 공정성을 완화하고, 다중 실행 큐 시나리오에서 각 실행 큐가 자체 지연 시간과 태스크 공정성을 유지해야 하는 복잡성을 제거하기 위함이었다.:ln 81–92 그는 MuQSS의 나중 버전에서는 BFS가 확정적인 지연 시간을 보장한다고 주장했다.:ln 471–472 그는 또한 CPU가 증가함에 따른 잠금 경합 문제(태스크 노드 데이터 변경, 제거, 생성과 관련됨):ln 126–144와 다음 태스크 실행 조회를 위한  오버헤드를 인식했다.:ln 472–478 MuQSS는 이러한 문제를 해결하려고 시도했다.
콜리바스는 나중에 2016년 BFS v0.480 릴리스에서 설계를 스킵 리스트로 변경했다. 이로 인해 스케줄러의 효율성이 변경되었다. 그는  태스크 삽입,  태스크 조회, 일 때  태스크 제거를 언급했다.:ln 4
브레인 퍽 스케줄러 이론적 설계 및 효율성
가상 마감일 공식은 현재 시간(niffy 단위 또는 내부 커널 시간 카운터인 나노초 jiffies)에 의해 상쇄된 nice 수준에 따라 스케일링된 라운드 로빈 타임슬라이스인 미래 마감 시간이다.:ln 4023, 4063 가상 마감일은 순서만 제안할 뿐, 태스크가 미래에 스케줄링된 niffy에 정확히 실행될 것이라고 보장하지는 않는다.:ln 161–163
먼저 prio 비율 조회 테이블이 생성된다.:ln 8042–8044 이는 재귀 수열을 기반으로 한다. 각 nice 수준마다 10%씩 증가한다.:ln 161 그래프로 그리면 포물선 패턴을 따르며, niced 태스크는 도메인으로 0에서 39(가장 높은 nice 우선순위부터 가장 낮은 nice 우선순위에 해당)까지, 범위로 128에서 5089까지 이동하는 제곱 함수로 분포된다.:ln 177–179, 120, 184–185 이동 부분은 콜리바스가 언급한 가상 마감일 공식의 t 변수에서 비롯된다.
브레인 퍽 스케줄러 이론적 설계 및 효율성
태스크의 nice-투-인덱스 매핑 함수 f(n)는 nice −20...19를 인덱스 0...39로 매핑하여 prio 비율 조회 테이블의 입력으로 사용된다. 이 매핑 함수는 커널 헤더의 sched.h에 있는 TASK_USER_PRIO() 매크로이다. 내부 커널 구현은 100에서 140 사이의 정적 우선순위 범위에서 약간 다르지만, 사용자들은 이를 −20...19 nice로 보게 된다.
가상 마감일은 이 정확한 공식에 기반한다::ln 4063, 4036, 4033, 1180
또는 다음과 같이 표현될 수 있다.
브레인 퍽 스케줄러 이론적 설계 및 효율성
여기서 d(n,t)는 nice n과 현재 시간 t(niffy 단위)의 함수로 u64 정수 나노초 단위의 가상 마감일이며, g(i)는 인덱스의 함수로 prio 비율 테이블 조회, f(n)은 태스크의 nice-투-인덱스 매핑 함수, T는 밀리초 단위의 라운드 로빈 타임슬라이스, N은 의 변환 계수를 나노초 단위의 1밀리초로 근사화한 지연 감소 상수로, 콜리바스는 그 규모와 비슷한 2의 거듭제곱 상수 N을 사용한다.:ln 1173–1174 d 값이 작을수록 가상 마감일이 빨라지며, 이는 음의 nice 값에 해당한다. d 값이 클수록 가상 마감일이 뒤로 밀리며, 이는 양의 nice 값에 해당한다. 타임슬라이스가 만료될 때마다 이 공식을 사용한다.:ln 5087
2진수 128은 10진수 100에 해당하며, 이는 "의사 100"일 가능성이 있다.:ln 3415 2진수 115는 10진수 90에 해당한다. 콜리바스는 "빠른 시프트"를 위해 128을 사용하는데,:ln 3846, 1648, 3525 이는 나눗셈이 2진수 오른쪽 시프트인 경우이다.
브레인 퍽 스케줄러 이론적 설계 및 효율성
BFS는 CPU 작업에 허용되는 태스크의 양을 결정하기 위해 스케줄링 정책을 사용한다. BFS는 최상위부터 최하위까지 4가지 스케줄링 계층(스케줄링 정책 또는 스케줄링 클래스라고 함)을 사용하여 태스크를 선택하는 방식을 결정하며,:ln 4146–4161 최상위 계층의 태스크가 먼저 실행된다.
각 태스크에는 prio라는 특별한 값이 있다. v0.462 버전(ck 4.0 커널 패치셋에서 사용됨)에서는 총 103개의 "우선순위 큐"(또는 prio) 또는 허용되는 값이 존재한다. 실제 특별한 자료 구조는 우선순위 큐로 사용되지 않았고, 이중 연결 리스트 실행 큐 자체만 사용되었다. prio 값이 낮을수록 중요도가 높고 먼저 실행된다.
브레인 퍽 스케줄러 이론적 설계 및 효율성
실시간 정책은 실시간 태스크를 위해 설계되었다. 이 정책은 실행 중인 태스크가 하위 prio 태스크 또는 하위 우선순위 정책 계층에 의해 중단(즉, 선점)될 수 없음을 의미한다. 스케줄러가 실시간 정책 하에서 고려하는 우선순위 클래스는 SCHED_RR 및 SCHED_FIFO로 표시된 태스크이다.:ln 351, 1150 스케줄러는 실시간 라운드 로빈(SCHED_RR)과 실시간 FIFO(SCHED_FIFO)를 다르게 처리한다.:ln 3881–3934
설계는 처음 100개의 정적 우선순위 큐를 설정했다.:ln 189
실행을 위해 선택될 태스크는 100개 큐 중 가장 낮은 prio 값의 태스크 가용성과 FIFO 스케줄링을 기반으로 한다.:ln 4146–4161
포크 시, 프로세스 우선순위는 일반 정책으로 강등된다.:ln 2708
실시간 정책 클래스에 대한 요청과 함께 sched_setscheduler가 비특권 사용자(즉, 비루트 사용자)에 의해 호출될 경우, 스케줄러는 태스크를 등시성 정책으로 강등한다.:ln 350–359, 5023–5025
등시성 정책은 루트가 아닌 사용자를 위한 거의 실시간 성능을 위해 설계되었다.:ln 325
브레인 퍽 스케줄러 이론적 설계 및 효율성
이 설계는 기본적으로 의사 실시간 태스크로 실행되지만, 실시간 수준으로 튜닝될 수 있는 하나의 우선순위 큐를 설정했다.:ln 1201, 346–348
이 정책의 동작은 태스크가 온라인 CPU 수와 타이머 해상도에 5초를 스케일링한 값에 1틱을 더한 튜닝 가능한 리소스 처리 비율(기본값 70%:ln 343, 432)을 초과할 경우 일반 정책으로 강등될 수 있다.:ln 343, 3844–3859, 1167, 338:ln 1678, 4770–4783, 734 다중 실행 큐 설계로 인해 MuQSS에서 공식이 변경되었다. 정확한 공식은 다음과 같다.
여기서 T는 등시성 틱의 총 수, F는 타이머 주파수, n은 온라인 CPU의 수, R은 소수점 대신 정수로 된 튜닝 가능한 리소스 처리 비율이다. 타이머 주파수는 기본적으로 250으로 설정되어 커널에서 편집 가능하지만, 일반적으로 서버의 경우 100Hz, 대화형 데스크톱의 경우 1000Hz로 튜닝된다. 250이 균형 잡힌 값이다. R을 100으로 설정하면 태스크가 실시간처럼 작동하고 0으로 설정하면 의사 실시간이 아니게 되며, 중간 값은 의사 실시간이다.:ln 346–348
브레인 퍽 스케줄러 이론적 설계 및 효율성
가장 빠른 가상 마감일을 가진 태스크가 실행을 위해 선택되지만, 여러 등시성 태스크가 존재할 경우, nice 수준을 고려하지 않고 라운드 로빈 방식으로 태스크를 스케줄링하여 튜닝 가능한 라운드 로빈 값(기본값 6ms)으로 태스크가 공정하게 차례로 실행될 수 있도록 한다.:ln 334
등시성 정책의 이러한 동작은 BFS 및 MuQSS에만 고유하며 다른 CPU 스케줄러에는 구현되지 않을 수 있다.:ln 324, 8484–8485:ln 1287–1288
일반 정책은 일반적인 사용을 위해 설계되었으며 기본 정책이다. 새로 생성된 태스크는 일반적으로 일반으로 표시된다.:ln 502
이 설계는 하나의 우선순위 큐를 설정했으며, 가장 빠른 가상 마감일에 따라 태스크가 먼저 실행되도록 선택된다.
유휴 우선순위는 분산 프로그램 및 트랜스코더와 같은 백그라운드 프로세스를 위해 설계되었으므로 포그라운드 프로세스 또는 이 스케줄링 정책 위에 있는 프로세스는 중단 없이 실행될 수 있다.:ln 363–368
이 설계는 1개의 우선순위 큐를 설정했으며, 태스크는 무한한 리소스 점유를 방지하기 위해 자동으로 일반 정책으로 승격될 수 있다.:ln 368
브레인 퍽 스케줄러 이론적 설계 및 효율성
동일한 우선순위 정책에 있는 다른 유휴 우선순위 태스크 중 다음에 실행될 태스크는 가장 빠른 가상 마감일에 따라 선택된다.:ln 4160–4161
선점은 더 높은 우선순위 정책(즉, 더 높은 prio)을 가진 새로 준비된 태스크가 현재 실행 중인 태스크보다 더 빠른 가상 마감일을 가질 때 발생할 수 있으며, 이 경우 현재 실행 중인 태스크는 스케줄링 해제되어 큐의 맨 뒤로 이동된다.:ln 169–175 스케줄링 해제는 가상 마감일이 업데이트되었음을 의미한다.:ln 165–166 태스크가 모든 시간을 사용했을 때, 태스크의 시간은 최대 라운드 로빈 퀀텀으로 다시 채워진다.:ln 4057–4062, 5856 스케줄러가 가장 빠른 가상 마감일을 가진 더 높은 prio의 태스크를 발견하면, 모든 논리적 CPU(하이퍼스레드 코어/SMT 스레드 포함)가 바쁜 경우에만 중요도가 낮은 현재 실행 중인 태스크 대신 실행된다. 스케줄러는 사용되지 않는 논리적 CPU가 있다면 가능한 한 오래 선점을 지연한다.
태스크가 유휴 우선순위 정책으로 표시된 경우, 다른 유휴 정책으로 표시된 태스크라도 전혀 선점할 수 없으며 협력적 멀티태스킹을 사용한다.:ln 2341–2344
브레인 퍽 스케줄러 이론적 설계 및 효율성
스케줄러가 비유니코어 시스템에서 깨어나는 태스크를 발견하면, 해당 태스크를 실행할 논리적 CPU를 결정해야 한다. 스케줄러는 태스크가 실행된 동일한 CPU에서 유휴 하이퍼스레드 코어(또는 유휴 SMT 스레드)를 가장 선호하고,:ln 261 그 다음은 멀티코어 CPU의 다른 유휴 코어,:ln 262 그 다음은 동일한 NUMA 노드의 다른 CPU,:ln 267, 263–266, 255–258 그 다음은 동일한 NUMA 노드에서 선점될 모든 바쁜 하이퍼스레드 코어/SMT 스레드/논리적 CPU,:ln 265–267 그 다음은 다른 (원격) NUMA 노드를 선호하며,:ln 268–270 이는 선호 목록에 따라 순위가 매겨진다.:ln 255–274 이 특별한 스캔은 태스크 마이그레이션으로 인한 지연 시간 오버헤드를 최소화하기 위해 존재한다.:ln 245, 268–272
선점 순서는 위 문단과 유사하다. 선점 순서는 동일한 멀티코어 내 하이퍼스레드 코어/SMT 단위가 먼저이고, 그 다음은 멀티코어 내 다른 코어, 그 다음은 동일한 NUMA 노드 내 다른 CPU이다.:ln 265–267 다른 원격 NUMA 노드에서 선점할 태스크를 스캔할 때, 선점은 해당 머신의 모든 논리적 CPU(하이퍼스레드 코어/SMT 스레드 포함)가 모두 바쁘다고 가정할 때, 낮은 prio 또는 동일한 prio 또는 나중 가상 마감일을 가진 바쁜 스레드에 대해 이루어진다.:ln 270 스케줄러는 선점할 낮은 우선순위 또는 동일한 우선순위 정책 태스크(필요한 경우 나중 가상 마감일을 가진)를 스캔하고, 선점할 수 없는 더 높은 우선순위 정책 태스크가 있는 논리적 CPU를 피해야 한다. 로컬 선점은 원격 유휴 NUMA 단위를 스캔하는 것보다 더 높은 순위를 갖는다.:ln 265–269
CPU 주파수 조절(CPU 주파수 거버너라고도 함)에 의해 CPU 속도가 느려져 태스크가 비자발적으로 선점될 때, 실시간 정책으로 표시된 태스크를 제외하고는 태스크에 특별히 "고정"(sticky) 표시가 된다.:ln 2085 고정 표시는 태스크가 아직 사용되지 않은 시간을 가지고 있으며, 태스크가 동일한 CPU에서만 실행되도록 제한됨을 나타낸다.:ln 233–243 CPU 스케일링 거버너가 CPU를 더 느린 속도로 스케일링할 때마다 태스크는 고정으로 표시된다.:ln 2082–2107, 8840–8848 유휴 상태로 고정된 태스크는 우연히 전체 Ghz 속도로 다시 실행되거나, 태스크가 실행된 동일한 CPU가 아닌 최적의 유휴 CPU에서 다시 스케줄링되어 실행된다.:ln 2082–2086, 239–242, 2068–2079 태스크를 다른 CPU나 NUMA 노드로 마이그레이션하는 오버헤드로 인해 지연 시간이 증가하기 때문에 태스크를 다른 곳으로 마이그레이션하는 것보다 유휴 상태로 두는 것이 바람직하지 않다.:ln 228, 245 이 고정 기능은 BFS의 마지막 버전(v0.512)에서 제거되었으며(콜리바스의 패치셋 4.8-ck1에 해당), MuQSS에는 존재하지 않았다.
브레인 퍽 스케줄러 schedtool
특권 사용자는 schedtool 프로그램을 사용하여 프로세스의 우선순위 정책을 변경하거나,:ln 326, 373 프로그램 자체에서 변경할 수 있다.:ln 336 우선순위 클래스는 코드 수준에서 시스템 호출인 sched_setscheduler를 통해 조작될 수 있으며, 이는 루트에게만 허용된다. schedtool은 이 기능을 사용한다.
브레인 퍽 스케줄러 벤치마크
현대 연구에서 저자는 리눅스 커널 v3.6.2를 사용하여 BFS와 CFS를 여러 성능 기반 종점으로 비교했다. 이 연구의 목적은 바닐라 리눅스 커널의 컴플리틀리 페어 스케줄러(CFS)와 해당 커널에 ck1 패치셋이 적용된 BFS를 평가하는 것이었다. 7개의 다른 머신을 사용하여 성능 기반 지표를 사용하여 차이점이 존재하는지, 그리고 어느 정도까지 확장되는지 확인했다. 논리 CPU 수는 1개에서 16개까지 다양했다. 이러한 종점은 BFS의 주요 설계 목표에 포함되지 않았다. 결과는 고무적이었다.
BFS를 포함한 ck1 패치셋이 적용된 커널은 테스트된 거의 모든 성능 기반 벤치마크에서 CFS를 사용하는 바닐라 커널보다 1%에서 8% 더 우수한 성능을 보였다. 더 큰 테스트셋으로 추가 연구를 수행할 수 있지만, 평가된 7개 PC의 소규모 테스트셋을 기반으로 볼 때, 이러한 프로세스 큐잉, 효율성/속도 증가는 전반적으로 CPU 유형(모노, 듀얼, 쿼드, 하이퍼스레드 등), CPU 아키텍처(32비트 및 64비트) 및 CPU 다중성(모노 또는 듀얼 소켓)과는 무관하다.
브레인 퍽 스케줄러 벤치마크
또한 코어 2 듀오 및 코어 i7과 같이 일반적인 워크스테이션 및 노트북을 대표하는 여러 "현대" CPU에서 BFS는 모든 벤치마크에서 바닐라 커널의 CFS보다 일관되게 우수한 성능을 보였다. 효율성과 속도 향상은 작지만 상당했다.
브레인 퍽 스케줄러 채택
BFS는 다음 데스크톱 리눅스 배포판의 기본 스케줄러이다.
또한 BFS는 구글의 안드로이드 개발 저장소의 실험 브랜치에 추가되었다. 그러나 블라인드 테스트에서 개선된 사용자 경험을 보이지 않아 프로요 릴리스에는 포함되지 않았다.
브레인 퍽 스케줄러 MuQSS
BFS는 정식 명칭이 다중 큐 스킵 리스트 스케줄러(Multiple Queue Skiplist Scheduler)인 MuQSS로 대체되어 중단되었다. 주요 저자는 2021년 8월 말까지 MuQSS 작업을 중단했다.
MuQSS는 양방향 정적 배열 8레벨 스킵 리스트를 사용하며, 태스크는 정적 우선순위[큐](스케줄링 정책을 의미)와 가상 마감일에 따라 정렬된다.:ln 519, 525, 537, 588, 608 8은 캐시라인에 배열을 맞추기 위해 선택되었다.:ln 523 이중 연결 자료 구조는 태스크 제거 속도를 높이기 위해 선택되었다. 이중 스킵 리스트를 사용하면 태스크 제거가 O(1)에 불과한 반면, 윌리엄 푸의 원래 설계는 최악의 경우 이 소요된다.:ln 458
브레인 퍽 스케줄러 MuQSS
작업 삽입은 이다.:ln 458 다음 작업 실행을 위한 검색은 인데, 여기서 k는 CPU 수이다.:ln 589–590, 603, 5125 다음 작업 실행은 실행 큐당 이지만,:ln 5124 스케줄러는 CPU 간 작업 공정성을 유지하고, 지연 시간 또는 균형(NUMA 노드 간 액세스보다 동일 NUMA 노드에서 CPU 사용률 및 캐시 일관성을 최대화하기 위해)을 위해 다른 모든 실행 큐를 검사하므로 궁극적으로 이다.:ln 591–593, 497–501, 633–656 처리할 수 있는 최대 작업 수는 CPU당 실행 큐당 64k개이다.:ln 521 일부 구성에서는 CPU당 하나의 실행 큐를 사용하는 다중 작업 실행 큐를 사용하지만, 이전 버전인 BFS는 모든 CPU에 대해 하나의 작업 실행 큐만 사용했다.
브레인 퍽 스케줄러 MuQSS
태스크는 스킵 리스트에 실시간 정책 우선순위가 먼저 오고 유휴 정책 우선순위가 마지막으로 오는 방식으로 그래디언트(단계별 변화)로 정렬된다.:ln 2356–2358 일반 및 유휴 우선순위 정책은 nice 값을 사용하는 가상 마감일에 따라 정렬된다.:ln 2353 실시간 및 등시성 정책 태스크는 nice 값을 무시하고 선입 선출 (FIFO) 순서로 실행된다.:ln 2350–2351 동일한 키를 가진 새로운 태스크는 FIFO 순서로 배치되는데, 이는 새로운 태스크가 목록의 끝(즉, 수직으로 가장 위쪽 노드)에 배치되고, 0번째 레벨 또는 맨 아래쪽에 있는 태스크가 수직으로 가장 가까운 위쪽 및 헤드 노드에서 가장 먼 태스크보다 먼저 실행된다는 의미이다.:ln 2351–2352, 590 삽입 정렬에 사용되는 키는 정적 우선순위:ln 2345, 2365, 또는 가상 마감일이다.:ln 2363
사용자는 멀티코어 간에 실행 큐를 공유하거나 논리적 CPU당 하나의 실행 큐를 가질 수 있다.:ln 947–1006 실행 큐 공유 설계는 처리량과 맞바꾸어 지연 시간을 줄이려는 의도였다.:ln 947–1006
MuQSS가 도입한 새로운 동작은 타임슬라이스가 소진되어 태스크를 다시 스케줄링할 때 밀리초 미만의 정확도를 위한 고해상도 타이머 사용이었다.:ln 618–630, 3829–3851, 3854–3865, 5316
메타데이터 (CLI)
메타데이터(Metadata)는 공통 언어 기반 (CLI)에서 코드의 상위 수준 구조를 설명하는 공통 중간 언어 (CIL) 코드 내에 포함된 특정 데이터 구조를 말한다. 메타데이터는 어셈블리에 정의된 모든 클래스 및 클래스 멤버, 그리고 현재 어셈블리가 다른 어셈블리에서 호출할 클래스 및 클래스 메서드 멤버를 설명한다. 메서드의 메타데이터에는 클래스 (및 해당 클래스를 포함하는 어셈블리), 반환형 및 모든 메서드 매개변수를 포함하여 메서드의 완전한 설명이 포함된다.
CLI 언어 컴파일러는 메타데이터를 생성하고 이를 CIL을 포함하는 어셈블리에 저장한다. 런타임이 CIL을 실행할 때 호출된 메서드의 메타데이터가 호출하는 메서드에 저장된 메타데이터와 동일한지 확인한다. 이를 통해 메서드는 정확히 올바른 수의 매개변수와 정확히 올바른 매개변수 유형으로만 호출될 수 있다.
윈도우 8 및 윈도우 폰 8에 있는 윈도우 런타임 애플리케이션 플랫폼은 CLI 메타데이터 형식을 사용하여 지원되는 프로그래밍 언어로 작성된 코드에 대한 컴포넌트 인터페이스를 설명한다. 공통 언어 런타임 내에서의 사용 차이점은 어셈블리가 일반적으로 CIL 명령을 포함하지 않는다는 것이다.
메타데이터 (CLI) 특성
개발자는 특성을 통해 코드에 메타데이터를 추가할 수 있다. 특성에는 사용자 지정 특성과 의사 사용자 지정 특성의 두 가지 유형이 있으며, 개발자에게는 동일한 구문을 가진다. 코드의 특성은 컴파일러에게 메타데이터를 생성하라는 메시지이다. CIL에서는 상속 수정자, 범위 수정자 및 opcode 또는 스트림이 아닌 거의 모든 메타데이터도 특성으로 참조된다.
사용자 지정 특성은 System.Attribute 클래스를 상속하는 일반 클래스이다. 사용자 지정 특성은 다음 구문을 사용하여 모든 메서드, 속성, 클래스 또는 전체 어셈블리에서 사용할 수 있다: [AttributeName(optional parameter, optional name=value pairs)] 예시는 다음과 같다.
메타데이터 (CLI) 특성
사용자 지정 특성은 CLI에서 광범위하게 사용된다. Windows Communication Foundation은 특성을 사용하여 서비스 계약을 정의하고, ASP.NET은 이를 사용하여 메서드를 웹 서비스로 노출하며, LINQ to SQL은 이를 사용하여 클래스와 기본 관계형 스키마의 매핑을 정의하고, 비주얼 스튜디오는 이를 사용하여 개체의 프로퍼티를 그룹화하며, 클래스 개발자는 [Category] 사용자 지정 특성을 적용하여 개체 클래스의 범주를 나타낸다. 사용자 지정 특성은 애플리케이션 코드에 의해 해석되며 CLR에 의해 해석되지 않는다. 컴파일러가 사용자 지정 특성을 보면 CLR이 인식하지 못하는 사용자 지정 메타데이터를 생성한다. 개발자는 메타데이터를 읽고 이에 따라 작동하는 코드를 제공해야 한다. 예를 들어, 예시에 표시된 특성은 다음 코드로 처리될 수 있다.
메타데이터 (CLI) 특성
클래스 이름은 특성 이름에 매핑된다. Visual C# 컴파일러는 모든 특성 이름 끝에 문자열 "Attribute"를 자동으로 추가한다. 따라서 모든 특성 클래스 이름은 이 문자열로 끝나야 하지만 Attribute-접미사 없이 특성을 정의하는 것도 허용된다. 항목에 특성을 붙일 때 컴파일러는 리터럴 이름과 Attribute가 끝에 추가된 이름(즉, [Custom]을 작성하면 컴파일러는 Custom과 CustomAttribute를 모두 찾는다)을 모두 찾는다. 둘 다 존재하면 컴파일러는 실패한다. 모호성을 피하고 싶다면 특성에 "@"를 접두사로 붙일 수 있으므로 [@Custom]을 작성하면 CustomAttribute와 일치하지 않는다. 특성을 사용하면 클래스의 생성자가 호출된다. 오버로드된 생성자가 지원된다. 이름-값 쌍은 속성에 매핑되며, 이름은 속성 이름을 나타내고 제공된 값은 속성에 의해 설정된다.
때로는 특성을 무엇에 붙이고 있는지에 대한 모호성이 있다. 다음 코드를 고려해 보자.
메타데이터 (CLI) 특성
무엇이 주황색으로 표시되었는가? ExampleMethod인가, 그 반환 값인가, 아니면 전체 어셈블리인가? 이 경우 컴파일러는 기본값으로 설정되고 특성을 메서드에 붙인 것으로 간주한다. 의도한 바가 아니거나 작성자가 코드를 명확히 하고 싶다면 특성 대상을 지정할 수 있다. [return: Orange]를 작성하면 반환 값을 주황색으로 표시하고, [assembly: Orange]를 작성하면 전체 어셈블리를 표시한다. 유효한 대상은 assembly, field, event, method, module, param, property, return, type이다.
의사 사용자 지정 특성은 일반 사용자 지정 특성처럼 사용되지만 사용자 지정 핸들러가 없다. 대신 컴파일러는 특성을 내재적으로 인식하고 그러한 특성으로 표시된 코드를 다르게 처리한다. Serializable 및 Obsolete와 같은 특성은 의사 사용자 지정 특성으로 구현된다. 의사 사용자 지정 특성은 메타데이터를 설명하기에 적절한 구문이 있으므로 ILAsm에서 사용해서는 안 된다.
메타데이터 (CLI) 메타데이터 저장소
어셈블리에는 메타데이터 테이블이 포함된다. 이 테이블은 CIL 사양에 의해 설명된다. 메타데이터 테이블에는 0개 이상의 항목이 있으며 항목의 위치는 해당 인덱스를 결정한다. CIL 코드가 메타데이터를 사용할 때 메타데이터 토큰을 통해 사용한다. 이것은 상위 8비트가 적절한 메타데이터 테이블을 식별하고 나머지 24비트가 테이블에서 메타데이터의 인덱스를 제공하는 32-비트 값이다. 프레임워크 SDK에는 어셈블리의 메타데이터 테이블을 나열하는 metainfo라는 샘플이 포함되어 있지만, 이 정보는 개발자에게 거의 유용하지 않다. 어셈블리의 메타데이터는 닷넷 프레임워크 SDK에서 제공하는 ILDASM 도구를 사용하여 볼 수 있다.
CIL 표준에서 메타데이터는 ILAsm (어셈블리 언어) 형식, 저장소를 위한 디스크 표현 형식, 그리고 Portable Executable (PE, .exe 또는 .dll) 형식의 어셈블리에 포함되는 형식으로 정의된다. PE 형식은 디스크 표현 형식을 기반으로 한다.
메타데이터 (CLI) 리플렉션
리플렉션은 CLI 메타데이터를 읽는 데 사용되는 API이다. 리플렉션 API는 metainfo와 같은 도구에서 제공하는 리터럴 뷰 대신 메타데이터의 논리적 뷰를 제공한다. 닷넷 프레임워크 버전 1.1의 리플렉션은 클래스와 해당 멤버의 설명을 검사하고 메서드를 호출하는 데 사용될 수 있다. 그러나 메서드의 CIL에 대한 런타임 접근을 허용하지 않는다. 프레임워크 버전 2.0은 메서드의 CIL을 얻을 수 있도록 한다.
메타데이터 (CLI) 다른 메타데이터 도구
System.Reflection 네임스페이스 외에도 메타데이터를 처리하는 데 사용할 수 있는 다른 도구도 있다. 마이크로소프트 닷넷 프레임워크는 네이티브 코드로 구현된 CLR 메타데이터 조작 라이브러리를 제공한다. 메타데이터를 검색하고 조작하는 타사 도구로는 PostSharp 및 Mono Cecil도 사용할 수 있다.
마이크로소프트 컴파일 HTML 도움말
마이크로소프트 컴파일 HTML 도움말(Microsoft Compiled HTML Help, CHM)은 마이크로소프트 독점 온라인 도움말 포맷으로, HTML 페이지, 색인 및 기타 탐색 도구 모음으로 구성된다. 파일은 압축되어 .CHM 확장자를 가진 이진 형식으로 배포된다. 이 형식은 윈도우 도움말을 계승하기 위한 것이었다.
이 형식은 마이크로소프트가 설계했지만 성공적으로 역설계되었으며 현재 많은 문서 뷰어에서 지원된다.
마이크로소프트 컴파일 HTML 도움말 역사
CHM은 윈도우 95 OSR 2.5 출시와 함께 윈도우 도움말의 후속으로 도입되었다. 윈도우 NT 계열에서는 윈도우 NT 4.0에서 CHM 파일 지원이 도입되었으며 윈도우 11에서도 여전히 지원된다.
마이크로소프트는 HTML 도움말에 새로운 기능을 추가할 의도가 없다고 발표했다.
마이크로소프트 컴파일 HTML 도움말 파일 형식
도움말은 .chm 확장자를 가진 이진 파일로 제공된다. 여기에는 HTML 파일 세트, 하이퍼링크된 목차, 색인 파일이 포함된다. 파일 형식은 역설계되었으며 해당 문서는 자유롭게 사용할 수 있다.
파일은 마이크로소프트가 CHM 파일에 사용되는 일반 저장 파일 형식에 부여한 내부 이름인 "Info-Tech Storage Format"의 "ITSF" (in ASCII) 바이트로 시작한다.
CHM 파일은 다음 기능을 지원한다.
Microsoft Reader의 .lit 파일 형식은 HTML 도움말 CHM 형식의 변형이다. CHM 파일은 때때로 전자책에 사용된다.
마이크로소프트 컴파일 HTML 도움말 뷰어
마이크로소프트 윈도우 외에 다음 앱들이 CHM을 지원한다.
마이크로소프트 컴파일 HTML 도움말 생성기
마이크로소프트의 HTML 도움말 워크숍은 .HHP 파일 확장자를 가지며 특수한 형태의 INI 파일인 HTML 도움말 프로젝트 파일에 저장된 지침에 따라 CHM 파일을 생성한다.
라자루스와 프리 파스칼은 CHM 생성을 위한 Doxygen 유사 도구와 chmcmd라는 별도의 명령줄 컴파일러를 제공한다.
마이크로소프트 컴파일 HTML 도움말 기타 유틸리티
마이크로소프트 윈도우의 공식 뷰어(hh.exe)는 CHM 파일을 역컴파일할 수 있다. 마이크로소프트 HTML 도움말 워크숍과 7-Zip도 마찬가지이다. 캘리버와 arCHMage는 CHM을 다른 형식으로 변환할 수 있다.
플로우 샵 스케줄링
플로우 샵 스케줄링(flow-shop scheduling)은 컴퓨터 과학 및 운영 연구의 최적화 문제이다. 이는 최적 작업 스케줄링의 한 변형이다. 일반적인 작업 스케줄링 문제에서, 우리는 다양한 처리 시간을 가진 n개의 작업 J1, J2, ..., Jn을 가지며, 이를 다양한 처리 능력을 가진 m개의 기계에 스케줄링해야 한다. 이때 목표는 메이크스팬을 최소화하는 것이다. 메이크스팬은 전체 스케줄의 총 길이(즉, 모든 작업이 처리를 마쳤을 때)를 의미한다. 플로우 샵 스케줄링으로 알려진 특정 변형에서는 각 작업이 정확히 m개의 작업을 포함한다. 작업의 i번째 작업은 i번째 기계에서 실행되어야 한다. 어떤 기계도 동시에 두 개 이상의 작업을 수행할 수 없다. 각 작업의 각 작업에 대해 실행 시간이 지정된다.