> 백엔드 개발 > C++ > C 컴파일러가 '새로운' 연산자 호출을 최적화할 수 있습니까?

C 컴파일러가 '새로운' 연산자 호출을 최적화할 수 있습니까?

DDD
풀어 주다: 2024-12-02 08:49:09
원래의
894명이 탐색했습니다.

Can a C   Compiler Optimize Away `new` Operator Calls?

컴파일러가 힙 메모리 할당을 최적화할 수 있나요?

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿