`unsequenced`·`reproducible` 속성 — 최적화를 위한 계약
unsequenced·reproducible 속성 — 최적화를 위한 계약
컴파일러가 함수 호출을 마음껏 재배치하거나 병렬로 실행할 수 있다면 성능이 크게 좋아질 때가 있어요. 그런데 그걸 허용하려면 "이 함수는 어떤 부수 효과도 없고, 언제 불러도 같은 결과를 낸다"는 보증이 필요해요. C23의 [[unsequenced]]와 [[reproducible]] 속성은 바로 그 보증을 코드로 선언하는 장치예요.
출처: cppreference
본문
문법(Syntax)
[[unsequenced]] (1)
[[__unsequenced__]] (1)
[[reproducible]] (2)
[[__reproducible__]] (2)
- 함수가 effectless·idempotent·stateless·independent임을 나타내요.
- 함수가 effectless이고 idempotent임을 나타내요.
설명(Explanation)
이 속성들은 함수 선언자 또는 함수 타입을 가진 타입 지정자에 적용돼요. 해당 속성은 함수 타입의 속성이 됩니다.
Effectless(부수 효과 없음)
함수 호출의 한 평가(evaluation)가 effectless라 함은, 호출 동안 순서가 매겨진(sequenced) 어떤 저장 연산도 호출과 동기화되는 객체의 수정일 때를 말해요. 게다가 그 연산이 관찰 가능한 것이라면, 그 객체에 대한 모든 접근은 함수의 유일한 포인터 매개변수에 기반해야 해요.
Idempotent(멱등)
어떤 평가 E가 idempotent라 함은, E를 두 번째 다시 평가해도 (결과 값이 있다면) 원래 평가 바로 뒤에 이어 붙여도 결괏값이나 실행의 관찰 가능한 상태가 달라지지 않을 때를 말해요.
Stateless(상태 없음)
함수 F가 stateless라 함은, F 안이나 F가 호출하는 함수 안에서 static 또는 thread 저장 기간을 가진 객체의 정의가 모두 const이되 volatile로 한정되지 않을 때를 말해요.
Independent(독립)
함수 F가 independent라 함은, F에 대한 호출이 매개변수에 기반하지 않은 lvalue를 통해 어떤 객체 X를 관찰할 때, 같은 프로그램 실행 동안 F에 대한 모든 호출에서 X에 대한 모든 접근이 같은 값을 관찰한다는 뜻이에요. 접근이 포인터 매개변수에 기반한다면, X에 대한 어떤 접근도 P에 기반한 lvalue여야 하는 유일한 포인터 매개변수 P가 존재해야 해요.
객체 X가 함수 호출에 의해 관찰된다는 것은, 둘이 동기화되고, X가 호출에 국한되지 않으며, X의 수명이 함수 호출 전에 시작되고, 호출 동안 X에 대한 접근이 순서 매겨질 때를 말해요. 호출 전에 저장된 X의 (있을 경우) 마지막 값이 호출이 관찰하는 X의 값이에요.
참고(Notes)
이 속성들은 컴파일러 최적화를 위해 존재해요.
함수가 reproducible이면, 여러 번의 연속 호출을 단일 호출로 취급할 수 있어요.
함수가 unsequenced이면, 여러 번의 연속 호출을 단일 호출로 취급할 수 있을 뿐 아니라, 호출들을 병렬화하고 임의로 재배열할 수도 있어요.
더 알아보기
[[nodiscard]],[[noreturn]]과 함께 C23 속성의 쓰임새를 정리해 보면 좋아요.