컴파일러가 힙 메모리 할당을 최적화할 수 있나요?
new 연산자를 사용하여 메모리를 할당하는 다음의 간단한 C 코드를 고려해 보세요.
int main() { int* mem = new int[100]; return 0; }
컴파일러가 새 호출을 최적화하여 동적 메모리를 피할 수 있습니까? 할당?
컴파일러 동작
이 상황에서는 컴파일러마다 다르게 동작합니다. g 및 Visual Studio 2015는 전체 최적화가 활성화된 테스트에서 관찰된 것처럼 clang은 새로운 호출을 최적화하지 않는 반면,
컴파일러 최적화 이론적 근거
N3664에 따르면 : 나중에 C 14의 일부가 된 메모리 할당을 명확히 하여 컴파일러는 메모리 할당을 최적화할 수 있습니다. 이 최적화는 새 호출에 관찰 가능한 부작용이 없다는 가정을 기반으로 합니다.
As-If 규칙
그러나 초안의 as-if 규칙은 C 표준 섹션 1.9에서는 추상 기계의 관찰 가능한 동작을 에뮬레이트하기 위해 구현을 준수해야 합니다. new에서 예외를 던지면 부작용이 관찰될 수 있으므로 컴파일러가 새 호출을 최적화하는 것이 허용되지 않는다고 주장할 수 있습니다.
구현 세부 정보
켜기 반면에 new에서 언제 예외를 throw할지 결정하는 것은 구현 세부 사항이라고 주장할 수 있습니다. Clang은 잠재적으로 할당이 예외를 발생시키지 않을 것이라고 판단하여 as-if 규칙을 위반하지 않고 새 호출을 제거할 수 있습니다.
Non-Throwing Allocations
던지지 않는 new, new (std::nothrow) int[100] 버전을 사용하면 여전히 clang이 할당을 최적화할 수 있습니다. 이는 관찰 가능한 동작을 유발할 수 있는 전역 대체 연산자 new가 없음을 clang이 증명할 수 있기 때문입니다.
공격적 최적화
clang의 이전 버전에서는 심지어 다음 코드에서 볼 수 있듯이 더욱 공격적인 최적화가 이루어졌습니다.
#include <cstddef> extern void* operator new(std::size_t n); template<typename T> T* create() { return new T(); } int main() { auto result = 0; for (auto i = 0; i < 1000000; ++i) { result += (create<int>() != nullptr); } return result; }
이 코드는 최적화되었습니다. to:
main: # @main movl 00000, %eax # imm = 0xF4240 ret
효과적으로 전체 루프가 최적화되었습니다. 최신 버전의 clang은 이러한 공격적인 최적화를 수행하지 않습니다.
위 내용은 C 컴파일러가 '새로운' 연산자 호출을 최적화할 수 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!