2017-12-27 62 views
1

일부 코드를 더 빨리 실행하려고합니다.부동 소수점 코드 용 g ++ 최적화 스위치

  • 파라미터 (상수 배, INT)의 입력 값
  • 어레이 (상수 배)

출력된다

    : 입력으로서 고려 -이 지점 집중적 코드 부동
  • 값 배열 (double)
  • 자바 스크립트 매트릭스
현재 내가

g++-7 (Ubuntu 7.2.0-1ubuntu1~16.04) 7.2.0 

을 사용하고

다음과 같은 명령 행 : 내 메모리 G ++ 과거 컴파일러 제작 나은 코드에서

g++-7 -S -fPIC -O3 -DNDEBUG -funroll-loops -march=native -ffast-math \ 
-I $BOOST_DIR tmp.cpp -std=c++17 \ 
-D__forceinline='__attribute__((always_inline))' \ 
-frecord-gcc-switches -Wno-attributes 

는 - 그리고 훨씬 이러한 코드에 씹는되었다 더 길게. 나는 다양한 옵션을 재생하려고했지만, 단지

--param max-gcse-memory=1 

어떤 효과가있는 것 - 사용하거나이 인수를 사용하지 않는 사이입니다. 매개 변수 값의 변경 사항은 무시됩니다.

더 나은 코드에 대한 나의 기준은 vmul [sp] d 명령어와 비교하여 코드에서 vmov/mov 명령어의 양입니다. 더 나은 코드에는 더 적은 [v] mov 명령어가 있어야합니다.

내가 10766은 [V] MOV 명령이 매개 변수없이 11,325에 비해 얻고있다

--param max-gcse-memory=1 

를 사용하여. 이것은 1000 vmulpd와 1900 vmulsd를 비교합니다.이 숫자는 두 시도간에 어느 정도 일정합니다.

다시 - 컴파일 시간에 신경 쓰지 마십시오. 나는 더 나은 코드를 원한다. 그리고 내가 과거 (2010)에 기억했던 것에서 나는 훨씬 더 긴 컴파일 시간을 포함하여 더 나은 코드를 얻었다.

+0

이전 버전을 설치하고 비교할 수 없습니까? 또한 기본 아키텍처가 변경되지 않았습니까? – visibleman

+2

이 수준에서 mov vs mul을 계산하는 것은 실제적인 발견 적 방법이므로 대표 데이터에서 실행 시간을 비교해야합니다. –

답변

1

SIMD 명령어는 정렬 된 데이터가 필요할 수 있습니다. GCC가 불충분하게 정렬 된 데이터를 보호하기 위해 많은 코드를 생성하는 것 같습니다.

코드를 수정할 수있는 경우 aligned 속성 또는 더 나은 OpenMP SIMD pragma를 사용하면 도움이되는 것처럼 보입니다.

프로그램의 구조에 따라 LTO (-flto)가 큰 차이를 만들 수 있습니다 (예 : -fvisibility = hidden).

기본적으로 옵티마이 저는 가능한 많은 작업 공간을 제공하기 때문에 많은 여분의 코드를 삭제하여 SIMD 명령어에 맞게 올바르게 정렬 할 수 있습니다.

더 많은 ISA 확장을 사용하는 것이 좋습니다 ... AVX는 256 비트 벡터를 지원하므로 명령어로 두 배의 작업을 수행 할 수 있으며 CPU가 지원할 가능성이 큽니다. 실행 파일을 다른 컴퓨터에서 실행하려면 출하시 target_clones 특성을 사용하여 여러 ISA 확장에 대해 최적화 된 코드를 쉽게 생성 할 수 있습니다.

+0

OP는 CPU가 지원하는 모든 것을 가능하게하는'-march = native'를 사용하고 있습니다. skylake를 사용 중이면'-mtune = skylake'를 설정합니다. 'LTO'는 좋은 제안이지만, OpenMP는 gcc가 그것 없이도 몇몇 중요한 루프를 자동 벡터화 할 수 없다면 유용 할 수 있습니다 (예를 들어'__restrict '의 사용이 충분하지 않거나 OpenMP –

+0

아, 네가 맞아 - march = 네이티브를 놓쳤다 OpenMP는 또한 내가 여기서 말한 컨텍스트 인 정렬을 지정할 수있다. GCC가 코드를 벡터화하는 것처럼 들린다는 말을 기반으로, 그것은 또한 많은 사전 작업을 수행하는 것일 뿐이므로, 컴파일러가 물건 정렬을 알리고이를 적극적으로 최적화 (LTO + 가시성)하도록하는 것이 중요합니다. – nemequ

+0

예, gcc의 바닐라 자동 벡터화 전략은 완전히 풀립니다 스칼라 intros/outros는 내부 루프의 포인터 중 하나에 대한 정렬 경계에 도달합니다 (그러나 내부 루프에 대해서는 전혀 언 롤링하지 않습니다.) 넓은 벡터에서 (특히 좁은 정수 유형의 경우) 이것은 많은 코드 팽창입니다. https://stackoverflow.co를 참조하십시오. m :/questions/38552116/컴파일러 출력을 보는 방법에 대한 gcc-clang-assembly-output의 사용법 : TL : DR : http://gcc.godbolt.org/에 올려주세요. –