CPU とは
CPU(Central Processing Unit)とは、コンピュータの頭脳のような存在で、ソフトウェアや、マウスやキーボードといったハードウェアが想定通りに動作できるように処理します。CPUには、次のような標準的な構成要素があります。
- 演算装置
主記憶に格納されたデータに対して、四則演算や論理演算などを実行 - 制御装置
主記憶に格納されたプログラムを読み出して、デコーダによって命令を解読して様々な処理を実行 - クロック
CPUが処理を行う際に発する信号の速さを表した指標 - レジスタ群
CPU内にある記憶メモリ領域
これらのコンポーネントが連動して、高速なタスク並列処理が可能な環境が実現されています。CPUクロックの駆動に伴い、CPUは1秒間に数百の異なるタスクを高速に切り替えて実行します。そのためデスクトップの表示や、インターネット接続などといった動作を同時に行うことができます。
また、CPUには「コア」という概念があります。昨今はクロックの高速化が限界に達しており、上記のCPUを「コア」と呼び、 複数のコアを搭載して同時並行で複数の処理を行うことが主流になってきています。複数のコアというのは、ひとつのCPUに複数のCPUが内蔵されているようなイメージです。
GPU とは
GPU(Graphics Processing Unit)とは、数学的な計算能力を強化した特殊なプロセッサで、コンピューターグラフィックスや機械学習などのタスクに適しています。例えば、画像描写はレンダリングするために複雑な数学やそれらの複雑な数学が正しく動作するための並列計算が必要になります。画像描写の激しいビデオゲームなどでは、画面上に数百から数千のポリゴンが常に表示され、それぞれが個別の動き、色、照明などを持つことがあります。CPUはそのような負荷に対応できるようにはできておりません。そこで登場したのがGPUになります。GPUはCPUと同様、コアやメモリなどを搭載していますが、GPUは多数のコアによる並列データ処理に特化しており、グラフィックスの領域で用いられています。また、GPUはCPUよりも並列演算性能に優れ、行列演算が得意であることから、ディープラーニングの領域でもよく利用されるようになりました。
CPU と GPU の違い
CPUとGPUの違いとしてコア数と得意領域の違いを紹介します。
CPU | GPU | |
---|---|---|
コア数 | 数個 | 数千個 |
得意領域 | 連続的で複雑な計算処理 | 並列的な計算処理 |
コア数
コアはコンピュータの演算処理を行なっている場所であり、コア数が多いと一度に処理できる量が多くなります。CPUのコア数は一般的に2から8個に対してGPUは数千個におよびます。
得意領域
CPUは連続的で複雑な作業の処理が得意です。例えば、プログラムの命令を元に演算を行い、メモリやディスプレイ、マウス、キーボードなどを制御しながら命令を実行するような処理です。このような命令は順番に処理していく必要があり、コアが多ければ処理が速くなるわけではありません。対してGPUは単純作業の処理が得意です。例えば3Dグラフィックスなどの画像処理は単純な計算を大量に行う必要があるためGPUが適しています。
パフォーマンス比較
以下は、ニューラルネットワークが1563枚の画像を学習するコードになります。こちらのコードをGoogle Colab環境で、 CPU、GPUでそれぞれ実行してパフォーマンスを比較します。
import numpy as np
import matplotlib.pyplot as plt
import keras
from keras.datasets import cifar10
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.optimizers import Adam
(x_train, t_train), (x_test, t_test) = cifar10.load_data()
batch_size = 32
epochs = 1
n_class = 10
t_train = keras.utils.to_categorical(t_train, n_class)
t_test = keras.utils.to_categorical(t_test, n_class)
model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same', input_shape=x_train.shape[1:]))
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(256))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(n_class))
model.add(Activation('softmax'))
model.compile(optimizer=Adam(), loss='categorical_crossentropy', metrics=['accuracy'])
x_train = x_train / 255
x_test = x_test / 255
model.fit(x_train, t_train, epochs=epochs, batch_size=batch_size, validation_data=(x_test, t_test))
まずはCPUで実行します。255秒という結果が得られました。
1563/1563 [==============================] - 255s 163ms/step - loss: 1.4949 - accuracy: 0.4569 - val_loss: 1.0942 - val_accuracy: 0.6151
次にGPUで実行します。結果は9秒でした。
1563/1563 [==============================] - 9s 5ms/step - loss: 1.5829 - accuracy: 0.4223 - val_loss: 1.2229 - val_accuracy: 0.5606
このように、GPUを選択することで学習時間を大きく削減することが可能になります。
参考