programing

gcc에게 함수를 인라인으로 표시하지 말라고 어떻게 말할 수 있을까?

prostudy 2022. 5. 21. 08:53
반응형

gcc에게 함수를 인라인으로 표시하지 말라고 어떻게 말할 수 있을까?

소스 파일에 이 작은 기능이 있다고 가정하십시오.

static void foo() {}

그리고 나는 내 바이너리의 최적화된 버전을 만들지만 나는 이 기능이 (최적화를 위해) 인라인으로 표시되는 것을 원하지 않는다.인라이닝을 방지하기 위해 소스 코드에 추가할 수 있는 매크로가 있는가?

당신은 그것을 원한다.gcc-특정 속성.

이 함수 속성은 함수가 인라이닝을 위해 고려되는 것을 방지한다.함수에 부작용이 없는 경우, 함수 호출은 라이브지만 함수 호출이 최적화되도록 하는 인라이닝 이외의 최적화가 있다.이러한 전화가 최적화되지 않도록 하려면asm ("");

다음과 같이 사용하십시오.

void __attribute__ ((noinline)) foo() 
{
  ...
}

GCC에 대한 질문인 건 알지만 다른 컴파일러에 대한 정보도 좀 있으면 유용할 것 같아서.

GCC의 기능 속성은 다른 컴파일러들에게도 꽤 인기가 있다.최소한 다음과 같은 방법으로 지원된다.

  • () (확랑(확)에)__has_attribute(noinline))
  • Intel C/C++ 컴파일러(문서 내용이 형편없지만 16.0+에서 작동한다고 확신함)
  • Oracle Solaris Studio를 최소 12.2로 되돌림
  • ARM C/C++ 컴파일러를 4.1 이상으로 되돌리기
  • IBM XL C/C+++를 최소 10.1로 되돌림
  • 가 있는 7 TI 8.0+(=gcc 7 7.3+), 이우의 의회를 규정하게 .__TI_GNU_ATTRIBUTE_SUPPORT__)

또한 MSVC는 Visual Studio 7.1로 돌아갈 수 있도록 지원한다.아마도 인텔도 그것을 지지할 것이다. (그들은 GCC와 MSVC 둘 다와 호환되려고 노력한다.) 하지만 나는 그것을 검증하는 것을 귀찮게 하지 않았다.구문은 기본적으로 동일하다.

__declspec(noinline)
static void foo(void) { }

PGI 10.2+(그리고 아마도 이전 버전)는noinline다음 기능에 적용되는 실용성:

#pragma noinline
static void foo(void) { }

TI 6.0+는 C와 C++에서 다르게 작동하는 실용성을 지원한다.C++에서는 PGI와 유사하다.

#pragma FUNC_CANNOT_INLINE;
static void foo(void) { }

단, C에서 기능명은 다음과 같이 요구된다.

#pragma FUNC_CANNOT_INLINE(foo);
static void foo(void) { }

크레용 6.4+(아마도 이전)는 유사한 접근방식을 취하며 기능명을 요구한다.

#pragma _CRI inline_never foo
static void foo(void) { }

Oracle Developer Studio는 또한 기능 이름을 Forte Developer 6으로 되돌리는 실용성을 지원하지만, 최근 버전에서도 선언 이후가 필요하다는 점에 유의하십시오.

static void foo(void);
#pragma no_inline(foo)

자신이 얼마나 헌신적인가에 따라 어디에서나 통할 매크로를 만들 수 있지만, 선언은 물론 함수 이름을 주장으로 가질 필요가 있을 것이다.

OTOH, 만약 당신이 대부분의 사람들에게만 효과가 있는 어떤 것에 괜찮다면, 당신은 좀 더 미적으로 즐겁고 반복할 필요가 없는 것을 피할 수 있을 것이다.현재 버전의 HEDLEY_NEVENE_가 있는 헤들리를 위해 내가 취한 접근법이다.인라인 모양:

#if \
  HEDLEY_GNUC_HAS_ATTRIBUTE(noinline,4,0,0) || \
  HEDLEY_INTEL_VERSION_CHECK(16,0,0) || \
  HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
  HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
  HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
  HEDLEY_TI_VERSION_CHECK(8,0,0) || \
  (HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
#  define HEDLEY_NEVER_INLINE __attribute__((__noinline__))
#elif HEDLEY_MSVC_VERSION_CHECK(13,10,0)
#  define HEDLEY_NEVER_INLINE __declspec(noinline)
#elif HEDLEY_PGI_VERSION_CHECK(10,2,0)
#  define HEDLEY_NEVER_INLINE _Pragma("noinline")
#elif HEDLEY_TI_VERSION_CHECK(6,0,0)
#  define HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
#else
#  define HEDLEY_NEVER_INLINE HEDLEY_INLINE
#endif

헤들리를 사용하지 않으려면(단일 공용 도메인 / CC0 헤더) 버전 체크 매크로를 무리 없이 변환할 수 있지만, 내가 기꺼이 ☺을 넣을 수 있는 것 이상이다.

GCC는 '스위크'라고 불리는 스위치를 가지고 있다.

-fno-inline-small-functions

그러니 gcc를 호출할 때 그것을 사용해라.그러나 그 부작용은 다른 모든 작은 기능들 또한 비인접적이라는 것이다.

이를 위한 휴대용 방법은 포인터를 통해 함수를 호출하는 것이다.

void (*foo_ptr)() = foo;
foo_ptr();

비록 이것이 분기할 다른 지침을 생산하지만, 그것은 당신의 목표가 아닐 수도 있다.좋은 점을 말해주는데, 여기서 당신의 목표는 무엇인가?

static __attribute__ ((noinline))  void foo()
{

}

이것은 나에게 효과가 있었다.

사용noinline 속성:

int func(int arg) __attribute__((noinline))
{
}

당신은 아마도 외용으로 함수를 선언할 때와 함수를 작성할 때 둘 다 사용해야 할 것이다.

다음에 대한 컴파일러 오류가 발생할 경우__attribute__((noinline)), 다음을 시도해 보십시오.

noinline int func(int arg)
{
    ....
}

나는 gcc 7.2와 함께 일한다.나는 특별히 비인기 기능이 필요했다. 왜냐하면 그것은 도서관에서 인스턴스화되어야 했기 때문이다.나는 그것을 시도했다.__attribute__((noinline))뿐만 아니라 대답하다.asm("")대답하다둘 다 그 문제를 해결하지 못했다.

마지막으로, 함수 내부에서 정적 변수를 정의하면 컴파일러가 정적 변수 블록에서 공간을 할당하게 되고, 함수가 처음 호출될 때 그에 대한 초기화를 실행하게 될 것이라고 생각했다.

이것은 일종의 비열한 속임수지만 효과가 있다.

참조URL: https://stackoverflow.com/questions/1474030/how-can-i-tell-gcc-not-to-inline-a-function

반응형