3
5

TensorFlow.jsを使って、内蔵GPUにアクセスしてサクセス。

Last updated at Posted at 2024-08-27

タイトル: "少年プログラマーとN100CPUの挑戦"

ある日、小学3年生の男の子、光太郎はコンピュータの前で真剣な表情をしていました。

光太郎の使っているコンピュータは、インテルの最新N100CPUを搭載したものでした。このN100CPUには、内臓GPUという機能がついています。お父さんが「これで十分だよ」と言って買ってくれたものでしたが、光太郎は最近、もっと速く計算できるコンピュータが欲しいと思うようになりました。

学校の友達たちは、最新のゲーミングPCを持っている子もいて、彼らの話を聞くたびに、光太郎は少し羨ましく思いました。でも、光太郎のお小遣いは毎月少しだけで、そんな高いコンピュータを買うお金はありませんでした。

「どうにかして、このコンピュータで高速に計算を行う方法はないかな?」

光太郎は、コンピュータの内蔵GPUを使って計算速度を上げる方法を模索していました。せっかくGPUが付いているのに、その機能を有効に活用する手段がわからず、困っていたのです。光太郎は、様々なプログラムを試みるものの、GPUの性能を引き出すことができずにいました。

そんなある日、光太郎はプログラミングの本棚からJavaScriptの本を取り出しました。すると、TensorFlow.jsというライブラリを使えば、ブラウザ上でGPUにアクセスできることを知りました。TensorFlow.jsは、WebGLというAPIを通じて、ブラウザから内蔵GPUにアクセスできるというのです。

「これだ!このアイデアだ!」と光太郎は興奮しました。これなら、内蔵GPUを有効に活用する方法が見つかるかもしれないと感じました。光太郎はすぐにTensorFlow.jsを使って、内蔵GPUを使った行列の掛け算プログラムを書き直しました。

光太郎が新しいプログラムを実行すると、内蔵GPUを活用することで計算が格段に速くなったことがわかりました。「やった!これなら、もっと速く計算できるかもしれない!」

光太郎は、自分のコンピュータに内蔵されているGPUを最大限に活用する方法を見つけ、これからもさまざまなプログラムに挑戦する決意をしました。高いコンピュータは買えなかったけれど、工夫と知識で、自分の手元にあるコンピュータを最大限に活かすことができたのです。

行列の掛け算を行い、CPUと内蔵GPU(WebGL)での処理時間を比較するHTMLとJavaScriptコードです。これにより、ブラウザ上で行列のサイズを少しずつ大きくし、処理時間を比較できます。

実行結果。やはり、すごいパワーです。

image.png

image.png

コードの説明

コードをメモ帳などのテキストエディタに貼り付け、ファイルを「index.html」などの拡張子が.htmlのファイルとして保存します。その後、保存したファイルをブラウザで開けば、コードが実行されます。

HTML構造:

標準的なHTML文書の構造を持ちます。
ページのタイトル「Matrix Multiplication Timing: CPU vs GPU」を表示します。
ボタンをクリックすると、行列計算のテストが実行されます。
結果を表示するために、タグが使用されます。

CSSスタイル:

キャンバス()に対して境界線(border)とマージン(margin-top)を設定しています。

JavaScriptコード:

TensorFlow.jsライブラリを使用して、行列の掛け算をCPUまたはGPU上で実行し、処理時間を計測します。

関数clearCanvas():

キャンバスをクリアするための関数です。計算を再実行する際に以前の結果を消去するために使用します。
関数printResult(text, x, y):

結果をキャンバスに描画するための関数です。指定された位置にテキストを表示します。

関数multiplyMatrices(size, useGPU):

size×sizeのランダムな行列を生成し、CPUまたはGPUを使って行列掛け算を行います。useGPUがtrueの場合はGPUで、falseの場合はCPUで計算します。
performance.now()を使用して計算時間を計測し、その結果を返します。

関数runTest():

64×64から1024×1024まで、2倍ごとに行列サイズを増やしてテストを行い、CPUとGPUの計算時間を比較します。
計算結果はキャンバスに描画されます。

実行方法:

HTMLファイルをブラウザで開き、「Run Test」ボタンをクリックすると、行列サイズごとのCPUとGPUの計算時間が比較表示されます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Matrix Multiplication Timing: CPU vs GPU</title>
    <style>
        /* キャンバスのスタイルを設定 */
        canvas {
            border: 1px solid black;
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <h1>Matrix Multiplication Timing: CPU vs GPU</h1>
    <div>
        <!-- ボタンをクリックするとテストが実行される -->
        <button onclick="runTest()">Run Test</button>
        <!-- 結果を表示するためのキャンバス -->
        <canvas id="resultCanvas" width="600" height="300"></canvas>
    </div>

    <!-- TensorFlow.jsライブラリを読み込む -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@4.0.0"></script>
    <script>
        const canvas = document.getElementById('resultCanvas');
        const ctx = canvas.getContext('2d');

        /* キャンバスをクリアする関数 */
        function clearCanvas() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
        }

        /* 結果をキャンバスに表示する関数 */
        function printResult(text, x = 10, y = 20) {
            ctx.fillText(text, x, y);
        }

        /* 行列の掛け算を行い、時間を計測する関数 */
        async function multiplyMatrices(size, useGPU) {
            // size x sizeのランダム行列を作成
            const a = tf.randomNormal([size, size]);
            const b = tf.randomNormal([size, size]);

            const start = performance.now(); // 計測開始
            let result;

            if (useGPU) {
                // GPUを使用して行列掛け算を行う
                result = await tf.tidy(() => tf.matMul(a, b));
            } else {
                // CPUを使用して行列掛け算を行う
                result = await tf.tidy(() => tf.matMul(a, b).arraySync());
            }

            const end = performance.now(); // 計測終了

            // メモリを解放
            tf.dispose([a, b, result]);

            // 掛かった時間を返す
            return end - start;
        }

        /* テストを実行し、結果を表示する関数 */
        async function runTest() {
            clearCanvas(); // キャンバスをクリア
            let yPosition = 20;

            // 64x64から1024x1024まで、行列サイズを2倍ずつ増やしてテスト
            for (let size = 64; size <= 1024; size *= 2) {
                const cpuTime = await multiplyMatrices(size, false); // CPUでの計算時間
                const gpuTime = await multiplyMatrices(size, true);  // GPUでの計算時間

                // 結果をキャンバスに表示
                printResult(`Size: ${size}x${size} - CPU: ${cpuTime.toFixed(2)}ms, GPU: ${gpuTime.toFixed(2)}ms`, 10, yPosition);
                yPosition += 20; // 表示位置を少し下にずらす
            }
        }

        // 初期メッセージをキャンバスに表示
        ctx.font = '16px Arial';
        printResult('Click "Run Test" to compare CPU and GPU performance.');
    </script>
</body>
</html>

参考。

Intel N100 CPU内蔵GPUについて

  1. N100 CPU内蔵GPU (UHD Graphics)

名称: Intel UHD Graphics
コア数: 内蔵GPUの「コア数」は、通常のCPUのコア数とは異なり、通常は「Execution Units (EUs)」という単位で表されます。例えば、Intel UHD Graphics 620には24 EUsがあります。

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5