はじめに
AWS Lambdaは、ARM64(Graviton2)とx86_64の2種類のアーキテクチャで動作します。ARM64はモバイル向けや低消費電力が特徴のRISCアーキテクチャで、一方x86_64はサーバー向けに広く使われるCISCアーキテクチャです。
今回は、AWS LambdaでARM64とx86_64のパフォーマンスを、I/Oバウンド処理、CPUバウンド処理、並列処理の観点で比較しました。Pythonを用いたサンプルコードを実行し、メモリサイズごとの処理時間を測定しました。
サンプルコード
次のPythonコードをAWS LambdaでARM64とx86_64の両方で実行しました。このコードは以下の3種類の処理を行います。
- I/Oバウンド処理: ファイルの読み書きでI/O性能を測定。
- CPUバウンド処理: 浮動小数点演算を大量に行うことでCPUの性能を測定。
- 並列処理: スレッドを用いた並列計算のパフォーマンスを測定。
import time
import math
import threading
def io_bound_computation():
start_time = time.time()
# ファイルの読み書きでI/Oバウンド処理をシミュレート
filename = "/tmp/test_file.txt"
with open(filename, "w") as f:
for i in range(10**6):
f.write(f"{i}\n")
with open(filename, "r") as f:
lines = f.readlines()
end_time = time.time()
return end_time - start_time
def cpu_bound_computation():
start_time = time.time()
# 浮動小数点演算によるCPUバウンド処理
result = 0
for i in range(1, 10**6):
result += math.sqrt(i) * math.sin(i)
end_time = time.time()
return end_time - start_time
def parallel_computation():
start_time = time.time()
# 並列処理をシミュレート
def worker(result_list, index):
result = 0
for i in range(index * 10**5, (index + 1) * 10**5):
result += i
result_list[index] = result
num_threads = 4
threads = []
results = [0] * num_threads
for i in range(num_threads):
thread = threading.Thread(target=worker, args=(results, i))
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
return time.time() - start_time
def lambda_handler(event, context):
# 各処理の時間を測定
io_time = io_bound_computation()
cpu_time = cpu_bound_computation()
parallel_time = parallel_computation()
return {
'io_bound_time': io_time,
'cpu_bound_time': cpu_time,
'parallel_time': parallel_time
}
実験環境と前提条件
- AWS Lambdaの実行環境で、ARM64とx86_64の両方で同じコードを実行しました。
- メモリサイズを128MB、256MB、512MB、1024MBに設定してパフォーマンスを測定しました。
- 各処理にかかった実行時間を比較しています。
結果
下表は、ARM64とx86_64における各処理の実行時間を示しています。I/Oバウンド処理、CPUバウンド処理、並列処理のいずれにおいても、ARM64がx86_64よりも優れた結果を示しました。
Memory (MB) | ARM64 IO Bound Time (s) | x86_64 IO Bound Time (s) | ARM64 CPU Bound Time (s) | x86_64 CPU Bound Time (s) | ARM64 Parallel Time (s) | x86_64 Parallel Time (s) |
---|---|---|---|---|---|---|
128 | 3.999 | 5.517 | 2.493 | 4.057 | 0.278 | 0.362 |
256 | 1.973 | 2.668 | 1.185 | 1.880 | 0.173 | 0.196 |
512 | 0.997 | 1.318 | 0.580 | 0.935 | 0.112 | 0.099 |
1024 | 0.479 | 0.675 | 0.294 | 0.485 | 0.056 | 0.053 |
考察
- I/Oバウンド処理では、メモリサイズが大きくなるにつれて両アーキテクチャで実行時間が短縮されますが、ARM64の方が全体的にパフォーマンスが良い結果となりました。
- CPUバウンド処理では、浮動小数点演算が多いため、ARM64がより効率的な処理を行っていることが伺えます。
- 並列処理についても、ARM64がわずかに優れた結果を示しましたが、メモリサイズが増大するにつれx86_64との差は小さくなっています。
結論
この結果から、ARM64アーキテクチャ(AWS Graviton2)は、低消費電力でありながら、I/Oや計算負荷が高い処理においても優れたパフォーマンスを発揮することが確認されました。特に、AWS Lambda環境においてコスト効率の良い選択肢となる可能性があります。
最後に
Graviton2は最大34%優れた料金パフォーマンスがある!というのだけ知っていて「どうせ低消費電力化したからその分安くするけど、実行効率は原則少し落ちるからトントンくらい」ということだと思っていたのでこの結果には驚きました。もちろん複雑な処理が全てそうだとは言えないと思いますがこの結果だと数値以上の恩恵を受けられるんじゃないかと思います。
今度はarmでは動かない処理などで検証してみたくなりました。