Alibaba Cloud Compiler は、Clang/LLVM 13 をベースに Alibaba Cloud によって開発された C++ コンパイラであり、Clang/LLVM 13 のオープンソースコミュニティバージョンです。 Clang/LLVM 13 のすべてのオプションとパラメーターを継承し、Alibaba Cloud インフラストラクチャ向けに最適化されており、より良いユーザーエクスペリエンスを提供するための追加機能を提供します。 このトピックでは、Alibaba Cloud Linux 3 に Alibaba Cloud Compiler をインストールして使用し、高性能な C++ アプリケーションを迅速に構築する方法について説明します。
背景情報
GNU Compiler Collection (GCC) や他の Clang/LLVM バージョンと比較して、Alibaba Cloud Compiler はコンパイルとビルドの速度を大幅に改善します。
Alibaba Cloud Compiler は、プロファイルに基づく最適化 (PGO) などのさまざまな手法を採用して、コンパイルを高速化し、GCC などの他のコンパイラよりも高速に大規模な C++ コードを記述します。
Clang/LLVM リンカー (LLD) は、特に大きなバイナリ ファイルの処理において、GCC で使用される GNU リンカーよりも優れたパフォーマンスを発揮します。
Alibaba Cloud Compiler は C++20 モジュールをサポートしており、標準 C++ ライブラリを
std-moduleにモジュール化できます。std-moduleを使用すると、低コストでビジネスコードを変換し、コンパイルを高速化できます。
Alibaba Cloud Compiler は、Alibaba Cloud Compiler (LLVM) ThinLTO や AutoFDO などのテクノロジーを活用して、プログラムのパフォーマンスを向上させます。 Alibaba Cloud Compiler は、x86 や Arm64 など、さまざまなアーキテクチャで実行でき、パフォーマンスをさらに向上させるために、倚天 710 プロセッサ向けに調整されています。
Alibaba Cloud Compiler はコルーチンとモジュールをサポートし、モジュール化された標準ライブラリを提供します。 Alibaba Cloud は、コルーチンライブラリ、シリアル化ライブラリ、リモートプロシージャコール (RPC) ライブラリ、HTTP 機能など、C++ 開発者が一般的に使用するコンポーネントを含む yaLanTingLibs を提供しています。
説明yaLanTingLibs は、高性能で使いやすい C++ ユーティリティライブラリのコレクションであり、開発者はこれを使用して高性能で最新の C++ アプリケーションを構築できます。
前提条件
Alibaba Cloud Linux 3 を実行する Elastic Compute Service (ECS) インスタンスが作成されていること。 詳細については、「インスタンスの作成」をご参照ください。
Alibaba Cloud Compiler は Alibaba Cloud Linux 3 のみをサポートしています。
Alibaba Cloud Compiler のインストールと使用
Alibaba Cloud Compiler をインストールします。
sudo yum install -y alibaba-cloud-compilerlibstdc++-develをインストールします。libstdc++-develは、GNU 標準 C++ ライブラリのヘッダーファイルを提供します。sudo yum -y install libstdc++-devel環境変数をインポートします。
export PATH=/opt/alibaba-cloud-compiler/bin:$PATHコンパイルに Alibaba Cloud Compiler を使用します。
シンプルなコンパイル
hello.cppファイルを作成します。sudo vim hello.cppiキーを押して挿入モードに入り、次のコンテンツをコピーしてファイルに貼り付けます。#include <iostream> int main() { std::cout << "hello C++" << std::endl; return 0; }Escキーを押し、:wqと入力し、Enterキーを押してファイルを保存して閉じます。モジュール化された C++ コードをコンパイルします。
clang++ -O2 hello.cpp -o hello.cpp.outプログラムを実行します。
./hello.cpp.out次のコマンド出力は、プログラムが実行されていることを示しています。

C++20 コルーチンとモジュールの使用
Alibaba Cloud Compiler は、コンパイル効率とパフォーマンスの向上に役立つ C++20 コルーチンとモジュールをサポートしています。 コルーチンの例については、「RPC ライブラリの使用」および「HTTP ライブラリの使用」をご参照ください。
説明従来の関数呼び出しでは、関数は一度呼び出されると、完了するまで実行されます。 コルーチンは、関数の処理を一時停止して再開できるプログラミングの概念です。 この柔軟な制御フローメカニズムにより、非同期プログラミングとジェネレーターパターンの実装が簡素化されます。
従来の C++ プログラミングパラダイムでは、コードはヘッダーファイル (
.h/.hpp) とソースファイル (.cpp) に編成され、ヘッダーファイルは宣言を含めるために使用されます。 ヘッダーファイルで宣言を行い、#includeプリプロセッサディレクティブを使用して、宣言を必要とする各ソースファイルにヘッダーファイルのコピーを挿入します。 そのため、コンパイラは同じヘッダーファイルを繰り返し解析する可能性があり、コンパイル速度が低下します。 モジュールは、コードの編成とコンパイル効率を向上させる方法として導入されています。
Clang を使用して C++ プログラムをコンパイルする場合、次の表のパラメーターを設定できます。
パラメーター
説明
-std=コンパイルに使用する C++ 言語標準を指定します。
-std=c++20を指定すると、C++ コルーチンとモジュールが有効になります。--precompileモジュールユニットをバイナリ モジュール インターフェイス (BMI) ファイルにコンパイルします。
-fprebuilt-module-pathBMI ファイルを検索するパスを指定します。
-fstd-modules標準モジュール用のファイルをコンパイルすることを指定します。
-fmodules-export-all現在のモジュールのすべての宣言を
exportとしてマークします。-fmodules-export-macrosモジュールがマクロをエクスポートできるようにします。
-try-load-bmi-when-preprocessingプリプロセス中に BMI ファイルを検索します。
-fstd-module-path標準モジュールを検索するパスを指定します。
-fcoro-aligned-allocationC++ コルーチンに整列割り当てを優先します。
コンパイル例:
Hello.cppmファイルを作成します。sudo vim Hello.cppmiキーを押して挿入モードに入り、次のコンテンツをコピーしてファイルに貼り付けます。module; #include <iostream> export module Hello; export void hello() { std::cout << "Hello World!\n"; }Escキーを押し、:wqと入力し、Enterキーを押してファイルを保存して閉じます。use.cppファイルを作成します。sudo vim use.cppiキーを押して挿入モードに入り、次のコンテンツをコピーしてファイルに貼り付けます。import Hello; int main() { hello(); return 0; }Escキーを押し、:wqと入力し、Enterキーを押してファイルを保存して閉じます。モジュール化された C++ コードをコンパイルします。
# モジュールインターフェースをプリコンパイルして、Hello.pcm ファイルを作成します。 clang++ -std=c++20 Hello.cppm --precompile -o Hello.pcm # メインプログラムをコンパイルし、モジュールをリンクして、実行可能ファイル Hello.out を作成します。 clang++ -std=c++20 use.cpp -fprebuilt-module-path=. Hello.pcm -o Hello.outプログラムを実行します。
./Hello.out次のコマンド出力は、プログラムが実行されていることを示しています。

(オプション) yaLanTingLibs の使用
C++20 コルーチンと C++ テンプレートメタプログラミング機能に基づいてコルーチンライブラリ、シリアル化ライブラリ、RPC ライブラリ、および HTTP 機能を提供する yaLanTingLibs を使用できます。 詳細については、yalantinglibs および async_simple にアクセスしてください。
シリアル化ライブラリは、データのシリアル化と逆シリアル化に使用するソフトウェアライブラリです。 シリアル化とは、データ構造またはオブジェクトの状態を、ファイルまたはバッファに格納したり、ネットワーク経由で送信したりできる形式に変換するプロセスです。 逆シリアル化とは、格納または送信されたデータ構造またはオブジェクトの状態を元の状態に復元するプロセスです。
RPC は、プロセス間通信 (IPC) に使用されるライブラリです。 RPC を使用すると、C++ プログラムは、リモートマシン上の関数またはメソッドを、ローカルにあるかのように実行できます。 RPC は、ネットワーク伝送、シリアル化、逆シリアル化、ルートなどの詳細を抽象化し、開発者がアプリケーションのビジネスロジックに集中できるようにします。
HTTP は、分散型の協調的なハイパーメディア情報システムのためのアプリケーション層プロトコルです。
coro_httpは、C++20 コルーチンを使用して実装された、高性能で使いやすい HTTP ライブラリです。 これには、HTTP サーバーと HTTP クライアントが含まれており、ユーザーは HTTP アプリケーションを迅速に開発できます。
yaLanTingLibs をインストールします。
sudo yum install -y yalantinglibs-develyaLanTingLibs のシリアル化ライブラリ、RPC ライブラリ、および HTTP ライブラリを使用します。
シリアル化ライブラリの使用
test.cppファイルを作成します。sudo vim test.cppiキーを押して挿入モードに入り、次のコンテンツをコピーしてファイルに貼り付けます。#include <iostream> #include "ylt/struct_pack.hpp" struct person { int age; std::string name; }; int main() { person tom{.age=20,.name="tom"}; auto buffer = struct_pack::serialize(tom); auto tom2 = struct_pack::deserialize<person>(buffer); std::cout<<"age: "<<tom2.value().age<<", name: "<<tom2.value().name<<std::endl; return 0; }Escキーを押し、:wqと入力し、Enterキーを押してファイルを保存して閉じます。プログラムをコンパイルします。
clang++ test.cpp -std=c++20 -o testプログラムを実行します。
./test次のコマンド出力は、プログラムが実行されていることを示しています。

RPC ライブラリの使用
サーバー上に
server.cppファイルを作成します。sudo vim server.cppiキーを押して挿入モードに入り、次のコンテンツをコピーしてファイルに貼り付けます。#include "ylt/coro_rpc/coro_rpc_server.hpp" std::string ping(std::string ping) { return "Receive: " + ping + ". Return pong."; // 受信: ping. pong を返します。 } int main() { coro_rpc::coro_rpc_server server{1 , 8801}; server.register_handler<ping>(); return server.start(); }Escキーを押し、:wqと入力し、Enterキーを押してファイルを保存して閉じます。client.cppファイルを作成します。sudo vim client.cppiキーを押して挿入モードに入り、次のコンテンツをコピーしてファイルに貼り付けます。#include <iostream> #include "ylt/coro_rpc/coro_rpc_client.hpp" std::string ping(std::string); async_simple::coro::Lazy<void> example(){ coro_rpc::coro_rpc_client client; auto ec = co_await client.connect("localhost","8801"); assert(!ec); auto ret = co_await client.call<ping>("ping"); std::cout << ret.value() << std::endl; co_return; }; int main(){ async_simple::coro::syncAwait(example()); return 0; }Escキーを押し、:wqと入力し、Enterキーを押してファイルを保存して閉じます。サーバー側プログラムをコンパイルします。
clang++ server.cpp -I /usr/include/ylt/thirdparty -std=c++20 -o server -lpthreadクライアント側プログラムをコンパイルします。
説明クライアント側プログラムをコンパイルする前に、クライアントに Alibaba Cloud Compiler がインストールされ、環境変数がクライアントにインポートされていることを確認してください。 詳細については、「Alibaba Cloud Compiler のコンパイル」をご参照ください。
clang++ client.cpp -I /usr/include/ylt/thirdparty -std=c++20 -o client -lpthreadサーバーとクライアントで次のコマンドを実行して、サーバーとクライアントを起動します。
./server & ./client次のコマンド出力が返されます。 ログエントリには、RPC サーバーの起動、RPC サーバーが RPC リクエストをリッスンしていること、RPC クライアントが RPC リクエストを送信していること、RPC サーバーが RPC リクエストを処理していること、RPC クライアントが接続を閉じていることなど、プロセス全体が記述されています。

HTTP ライブラリの使用
サーバー上に
http.cppファイルを作成します。sudo vim http.cppiキーを押して挿入モードに入り、次のコンテンツをコピーしてファイルに貼り付けます。#include <iostream> #include "ylt/coro_http/coro_http_client.hpp" #include "ylt/coro_http/coro_http_server.hpp" using namespace std::chrono_literals; using namespace coro_http; async_simple::coro::Lazy<void> basic_usage() { coro_http_server server(1, 9001); server.set_http_handler<GET>( "/get", [](coro_http_request &req, coro_http_response &resp) { resp.set_status_and_content(status_type::ok, "ok"); }); server.async_start(); std::this_thread::sleep_for(300ms); coro_http_client client{}; auto result = co_await client.async_get("http://127.0.0.1:9001/get"); assert(result.status == 200); assert(result.resp_body == "ok"); for (auto [key, val] : result.resp_headers) { std::cout << key << ": " << val << "\n"; } } int main() { async_simple::coro::syncAwait(basic_usage()); }Escキーを押し、:wqと入力し、Enterキーを押してファイルを保存して閉じます。HTTP プログラムをコンパイルします。
clang++ http.cpp -I /usr/include/ylt/thirdparty -std=c++20 -o http -lpthreadHTTP プログラムを実行します。
./http次のコマンド出力は、プログラムが実行されていることを示しています。
