현대 컴퓨터의 탄생과 함께 어떻게 하면 더 빠르고 더 작은 코드를 컴파일할 수 있는가 하는 문제가 대두되었습니다.
컴파일 최적화는 비용 대비 이익 비율이 가장 높은 최적화 방법입니다. 더 나은 코드 최적화는 대규모 데이터 센터 애플리케이션의 운영 비용을 크게 줄일 수 있습니다. 컴파일된 바이너리는 엄격한 코드 크기 예산을 충족해야 하므로 컴파일된 코드 크기는 보안 부팅 파티션에 배포된 모바일 및 임베디드 시스템이나 소프트웨어에 매우 중요합니다. 분야가 발전함에 따라 점점 더 복잡해지는 휴리스틱은 제한된 시스템 공간을 심각하게 압박하여 유지 관리 및 추가 개선을 방해합니다.
최근 연구에 따르면 기계 학습은 복잡한 경험적 방법을 기계 학습 전략으로 대체하여 컴파일러 최적화에서 더 많은 기회를 열어줄 수 있습니다. 그러나 범용 산업 등급 컴파일러에서 기계 학습 전략을 채택하는 것은 여전히 어려운 과제입니다.
이 문제를 해결하기 위해 Google의 수석 엔지니어인 Yundi Qian과 Mircea Trofin이 "머신러닝 기반 컴파일러 최적화 프레임워크인 MLGO"를 제안했습니다. 이는 머신러닝을 변환하기 위한 최초의 산업급 일반 프레임워크입니다. 기술은 미션 크리티컬 고성능 소프트웨어 구축에 널리 사용되는 오픈 소스 산업용 컴파일러 인프라인 LLVM에 체계적으로 통합됩니다.
논문 주소: https://arxiv.org/pdf/2101.04808.pdf
MLGO는 강화 학습을 사용하여 신경망을 훈련시켜 LLVM의 휴리스틱 알고리즘을 대체하기 위한 결정을 내립니다. 저자의 설명에 따르면 LLVM에는 두 가지 MLGO 최적화가 있습니다.
1) 인라인을 통해 코드 크기 줄이기
2) 레지스터 할당을 통해 코드 성능 향상.
두 가지 최적화 모두 LLVM 저장소에서 사용할 수 있으며 프로덕션 환경에 배포되었습니다.
인라이닝은 중복 코드를 제거하는 결정을 내려 코드 크기를 줄이는 데 도움이 됩니다. 아래 예에서 호출자 함수 <code style="font-family: monospace; font-size: 12px; background-color: rgba(0, 0, 0, 0.06); padding: 0px 2px; border-radius: 6px; line-height: inherit; overflow-wrap: break-word; text-indent: 0px;"><span style="font-size: 15px;">foo()</span>
调用被调用者函数 <span style="font-size: 15px;">bar()</span>
,而 <span style="font-size: 15px;">bar()</span>
本身又调用了 <span style="font-size: 15px;">baz()</span>
。内联这两个调用站点将返回一个简单的 <code style="font-family: monospace; font-size: 12px; background-color: rgba(0, 0, 0, 0.06); padding: 0px 2px; border-radius: 6px; line-height: inherit; overflow-wrap: break-word; text-indent: 0px;"><span style="font-size: 15px;">foo()</span>foo()호출자 함수 호출
<p style="text-align: center;">bar()<img src="https://img.php.cn/upload/article/000/000/164/168291834816871.png" alt="内存减少3%-7%!谷歌提出用于编译器优化的机器学习框架 MLGO"></p>
, <span style="font-size: 12px;">bar()<span style="color: #888888;"> code></span> 자체는 </span><code style="font-family: monospace; 글꼴 크기: 12px; background-color: rgba(0, 0, 0, 0.06); padding: 0px 2px; border -radius: 6px를 호출합니다. ; 줄 높이: 상속; 오버플로 랩: 텍스트 들여쓰기: 0px;">
🎜foo()🎜
🎜 함수를 사용하면 코드 크기가 줄어듭니다. 🎜🎜🎜🎜🎜🎜🎜🎜캡션: 인라인은 중복 코드를 제거하여 코드 크기를 줄입니다🎜🎜🎜실제 코드에는 수천 개의 함수가 서로를 호출하여 호출 그래프를 형성합니다. 인라인 단계 동안 컴파일러는 모든 호출자-호출 수신자 쌍의 호출 그래프를 순회하고 호출자-호출 수신자 쌍을 인라인할지 여부를 결정합니다. 이전 인라인 결정으로 인해 호출 그래프가 변경되어 후속 결정과 최종 결과에 영향을 미치기 때문에 이는 지속적인 의사 결정 프로세스입니다. 위의 예에서 호출 그래프는 <code style="font-family: monospace; font-size: 12px; background-color: rgba(0, 0, 0, 0.06); padding: 0px 2px; border-radius: 6px; line-height: inherit; overflow-wrap: break-word; text-indent: 0px;"><span style="font-size: 15px;">foo()</span>
→ <span style="font-size: 15px;">bar()</span>
→ <span style="font-size: 15px;">baz()</span>
foo() →
<p style="text-align: justify;">bar()<span style="font-size: 15px;"></span></p>
→ <p style="text-align: center;">baz()<img src="https://img.php.cn/upload/article/000/000/164/168291834817462.gif" alt="内存减少3%-7%!谷歌提出用于编译器优化的机器学习框架 MLGO"></p>
코드 크기를 작게 유지하려면 양쪽에서 "예" 결정을 내려야 합니다. MLGO 이전에는 인라인/비인라인 결정이 시간이 지남에 따라 개선하기가 점점 어려워지는 경험적 방법에 의해 이루어졌습니다. MLGO는 휴리스틱을 기계 학습 모델로 대체합니다. 호출 그래프를 순회하는 동안 컴파일러는 입력 그래프의 관련 기능(즉, 입력)을 통해 특정 호출자-호출 수신자 쌍을 인라인할지 여부에 대한 신경망의 권장 사항을 찾고 전체 호출 그래프가 나올 때까지 순차적으로 결정을 실행합니다. 도달했습니다.
Illustration: 인라인 프로세스 중 MLGO의 그림 "#bbs", "#users" 및 "callsite height"는 호출자-호출 수신자 쌍 속성의 인스턴스입니다
MLGO는 정책 그라데이션을 사용하고 의사결정 네트워크의 RL 훈련을 위한 진화적인 정책 알고리즘. 최적의 결정에 대한 근거 진실은 없지만 온라인 RL은 훈련과 어셈블리 실행을 반복하는 훈련된 정책을 사용하여 데이터를 수집하고 정책을 개선합니다. 특히 현재 훈련 중인 모델의 경우 컴파일러는 인라인 단계에서 모델을 참조하여 인라인/인라인 아님 결정을 내립니다. 컴파일 후에는 순차적인 결정 프로세스(상태, 행동, 보상)에 대한 로그를 생성합니다. 그런 다음 이 로그는 트레이너에게 전달되어 모델을 업데이트합니다. 이 과정은 만족스러운 모델이 얻어질 때까지 반복됩니다.
캡션: 훈련 중 컴파일러 동작
- 컴파일러는 소스 코드 foo.cpp를 객체 파일 foo.o로 컴파일하고 일련의 최적화를 수행하며 그 중 하나가 인라인 통신 경로입니다. 훈련된 정책이 컴파일러에 내장되어 컴파일 프로세스 중에 인라인/비인라인 결정을 제공합니다. 학습 시나리오와 달리 이 전략은 로그를 생성하지 않습니다. TensorFlow 모델은 모델을 실행 가능한 코드로 변환하는 XLA AOT에 내장되어 있습니다. 이렇게 하면 TensorFlow 런타임 종속성과 오버헤드가 방지되어 컴파일 시 ML 모델 추론으로 인해 발생하는 추가 시간과 메모리 비용이 최소화됩니다.
캡션: 프로덕션에서의 컴파일러 동작 🎜🎜🎜🎜🎜 우리는 30,000개의 모듈이 포함된 대규모 내부 패키지에서 크고 작은 인라인 전략을 훈련했습니다. 훈련된 전략은 다른 소프트웨어를 컴파일할 때 일반화될 수 있으며, 시간과 메모리 오버헤드를 3%~7% 줄입니다. 🎜소프트웨어 전반에 걸친 일반성 외에도 시간에 따른 일반성도 중요합니다. 소프트웨어와 컴파일러 모두 활발하게 개발되고 있으므로 합리적인 시간 내에 좋은 성능을 유지하려면 잘 훈련된 전략이 필요합니다. 3개월 후에 동일한 소프트웨어 세트에서 모델 성능을 평가한 결과 약간의 저하가 발견되었습니다. 🎜🎜
차트: 인라인 크기 전략 크기 감소 비율, x축은 다양한 소프트웨어를 나타내고 y축은 감소 비율을 나타냅니다. "Training"은 모델을 훈련시키는 소프트웨어이고 "InfraX"는 다른 내부 소프트웨어 패키지입니다.
MLGO의 인라인 크기 조정 교육은 바이너리 크기가 핵심인 다양한 하드웨어 및 소프트웨어 생태계를 지원하도록 설계된 범용 오픈 소스 운영 체제인 Fuchsia에 배포되었습니다. 여기서 MLGO는 C++ 번역 단위 크기가 6.3% 감소한 것을 보여줍니다.
일반적인 프레임워크로 MLGO를 사용하여 레지스터 할당 채널을 개선하여 LLVM의 코드 성능을 향상시킵니다. 레지스터 할당은 활성 범위(예: 변수)에 물리적 레지스터를 할당하는 문제를 해결합니다.
코드가 실행되면 서로 다른 라이브 범위가 서로 다른 시간에 완료되고 레지스터는 후속 처리 단계에서 사용할 수 있도록 해제됩니다. 다음 예에서 각 "더하기" 및 "곱하기" 명령어를 사용하려면 모든 피연산자와 결과가 물리적 레지스터에 있어야 합니다. 실시간 범위 x는 녹색 레지스터에 할당되고 파란색 또는 노란색 레지스터의 실시간 범위 전에 완료됩니다. x가 완료된 후 녹색 레지스터를 사용할 수 있게 되고 라이브 범위 t에 할당됩니다.
코드 실행 중에는 서로 다른 실시간 범위가 서로 다른 시간에 완료되고 해제된 레지스터는 후속 처리 단계에서 사용됩니다. 아래 예에서 각 "더하기" 및 "곱하기" 명령어를 사용하려면 모든 피연산자와 결과가 물리적 레지스터에 있어야 합니다. 활성 범위 x는 녹색 레지스터에 할당되고 파란색 또는 노란색 레지스터의 라이브 범위 전에 완료됩니다. x가 완료된 후 녹색 레지스터를 사용할 수 있게 되고 라이브 범위 t에 할당됩니다.
캡션: 레지스터 할당 예
활성 범위 q가 할당되면 사용 가능한 레지스터가 없으므로 레지스터 할당 채널은 레지스터에서 "제거"될 수 있는 활성 범위를 결정해야 합니다. q를 위한 공간을 확보하세요. 이를 "필드 퇴거(field eviction)" 문제라고 하며, 원래의 휴리스틱 결정을 대체하기 위해 모델을 훈련하는 곳입니다. 이 예에서는 노란색 레지스터에서 z를 제거하고 이를 q와 z의 전반부에 할당합니다.
이제 실제 범위 z의 할당되지 않은 하위 절반을 고려합니다. 또 다른 충돌이 있습니다. 이번에는 활성 범위 t가 제거되고 분할되며, t의 전반부와 z의 마지막 부분은 결국 녹색 레지스터를 사용하게 됩니다. Z의 중간 부분은 명령어 q = t * y에 해당하며, 여기서 z는 사용되지 않으므로 어떤 레지스터에도 할당되지 않고 그 값은 노란색 레지스터에서 스택에 저장되었다가 나중에 녹색 레지스터로 다시 로드됩니다. . t에서도 같은 일이 일어납니다. 이는 코드에 추가 로드/저장 명령을 추가하고 성능을 저하시킵니다. 레지스터 할당 알고리즘의 목표는 이러한 비효율성을 최소화하는 것입니다. 이는 RL 정책 훈련을 안내하기 위한 보상으로 사용됩니다.
인라인 크기 조정 정책과 유사하게 레지스터 할당(regalloc-for-Performance) 정책은 Google 내의 대규모 소프트웨어 패키지에 대해 교육되었으며 다양한 소프트웨어에 걸쳐 일반화되고 일련의 내부 대규모 데이터 센터에 적용될 수 있습니다. 프로그램의 초당 쿼리 수(QPS)가 0.3% ~ 1.5% 증가했습니다. QPS의 개선은 배포 후 몇 달 동안 지속되어 모델의 일반화 가능성을 입증했습니다.
MLGO는 강화 학습을 사용하여 신경망을 훈련하여 의사 결정을 내립니다. 이는 복잡한 경험적 방법을 대체하는 기계 학습 전략입니다. 일반적인 산업 등급 프레임워크로서 인라인 및 레지스터 할당뿐만 아니라 더 많은 환경에서 더 깊고 더 광범위하게 사용될 것입니다.
MLGO는 1) 더 많은 기능을 추가하고 더 나은 RL 알고리즘을 적용하는 등 더 심층적으로 개발할 수 있습니다. 2) 인라인 및 재배포 방법을 넘어 더 많은 최적화 휴리스틱을 적용할 수 있습니다.
저자는 MLGO가 컴파일러 최적화 분야에 가져올 수 있는 가능성에 대해 열광하고 있으며 연구 커뮤니티의 추가 채택과 향후 기여를 기대합니다.
위 내용은 메모리 3%~7% 감소! Google은 컴파일러 최적화를 위한 기계 학습 프레임워크 MLGO를 제안합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!