カーネルパラメータ設定
Brainuxに合わせたカーネルパラメータを考えてみました。
使い方によっては、調整してみてください。
sudo vi sysctl.conf
###############################################
# Brainux ARMv5 最適化 sysctl.conf
# 目的:低RAM・低速CPU・低速I/O環境での体感速度向上
###############################################
########## メモリ最適化 ##########
# swap を極力使わない(フリーズ防止)
vm.swappiness = 0
# ファイルキャッシュを積極的に保持(ゲームの画像・音声が速くなる)
vm.vfs_cache_pressure = 50
# 書き込み遅延を減らして I/O フリーズを防ぐ
vm.dirty_ratio = 5
vm.dirty_background_ratio = 2
# dirty 書き込みを早めに開始(SDカードの詰まり防止)
vm.dirty_expire_centisecs = 1000
vm.dirty_writeback_centisecs = 300
########## CPU スケジューラ最適化 ##########
# fork 直後の子プロセスを優先しない(カクつき防止)
kernel.sched_child_runs_first = 0
# インタラクティブ処理を優先(SDLゲームの反応改善)
#kernel.sched_latency_ns = 6000000
#kernel.sched_min_granularity_ns = 750000
#kernel.sched_wakeup_granularity_ns = 1000000
########## ネットワーク(軽量化) ##########
# TCP バッファを小さくしてメモリ節約
net.ipv4.tcp_rmem = 4096 87380 131072
net.ipv4.tcp_wmem = 4096 65536 131072
# TIME_WAIT を減らして軽量化
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
########## カーネル動作の軽量化 ##########
# カーネルログの出力を抑制(ゲーム中のカクつき防止)
kernel.printk = 3 3 3 3
# カーネルの OOM killer を積極化(フリーズ防止)
vm.oom_kill_allocating_task = 1
vm.panic_on_oom = 0
###############################################
# 以上
###############################################
この設定ファイルの内容での即時反映は、以下のコマンドで可能です。
$ sudo sysctl -p
設定の確認は、以下のようなコマンドで可能です。
$ sysctl vm.swappiness
vm.swappiness = 0
$ sysctl -a
sysctl.conf 最適化項目の解説
| カテゴリ | パラメータ | 設定値 | 変更の狙い(電子辞書環境への効果) |
|---|---|---|---|
| メモリ | vm.swappiness | 0 | SDカードへのスワップを極限まで禁止。 物理RAMが本当にゼロになるまで1GBのスワップファイルへの書き込みを拒否し、SDカードのI/Oによる「突発的なフリーズ(プチフリ)」を力技で防止する。 |
| メモリ | vm.vfs_cache_pressure | 50 | ゲームの読み込みを高速化。 ディレクトリやファイルのキャッシュ(VFSキャッシュ)をメモリ上に長く保持させ、ゲーム中の画像や音声データの再読み込みによるカクつきを減らす。 |
| I/O | vm.dirty_ratio | 5 | SDカードの「プチフリ」防止(第1弾)。 メモリ上に溜め込める未書き込みデータの上限を物理RAMの5%に制限。データが大量に溜まってから一気にSDカードへ書き込まれることによる、システム全体の数秒間のフリーズを防ぐ。 |
| I/O | vm.dirty_background_ratio | 2 | SDカードの「プチフリ」防止(第2弾)。 未書き込みデータが2%に達した時点で、裏で少しずつSDカードへの書き込み(バックグラウンドフラッシュ)を開始させる。 |
| I/O | vm.dirty_expire_centisecs | 1000 | 書き込み猶予の短縮。 メモリ上にデータが生まれてから10秒(1000センチ秒)経ったら書き込み対象にする。データを長く持ちすぎず、小まめにSDカードへ流す。 |
| I/O | vm.dirty_writeback_centisecs | 300 | 書き込みプロセスの頻繁な起動。 3秒(300センチ秒)に1回、バックグラウンドの書き込みスレッドを起動してメモリをチェックさせる。これによりI/O負荷を極小に分散する。 |
| CPU | kernel.sched_child_runs_first | 0 | 親プロセスのカクつき防止。 プロセスが新しく子プロセスを作った(forkした)際、子プロセスを無理に優先させず親プロセスの処理を継続する。ゲームのバックグラウンド処理などで一瞬挙動が重くなるのを防ぐ。 |
| ネット | net.ipv4.tcp_rmem | 4096 87380 131072 | 受信バッファの制限。 ネットワーク受信に使うメモリ上限を最大128KBに制限し、貴重な物理RAMの浪費を徹底的に抑える。 |
| ネット | net.ipv4.tcp_wmem | 4096 65536 131072 | 送信バッファの制限。 ネットワーク送信に使うメモリ上限を最大128KBに制限し、上記同様にメモリを節約する。 |
| ネット | net.ipv4.tcp_fin_timeout | 15 | 切断待ちの高速化。 通信が切断された後の無駄な待ち時間を15秒に短縮し、通信用のソケットリソースを素早く解放する。 |
| ネット | net.ipv4.tcp_tw_reuse | 1 | ソケットの再利用。 TIME_WAIT 状態にある古いソケットを新しい通信で即座に使い回し、カーネルのメモリ消費と管理負荷を減らす。 |
| カーネル | kernel.printk | 3 3 3 3 | ログ出力によるCPU負荷の軽減。 画面(コンソール)やバックグラウンドへのシステムログ出力レベルを制限し、ゲームプレイ中などにログ書き込みの負荷でガタつくのを防ぐ。 |
| カーネル | vm.oom_kill_allocating_task | 1 | 完全フリーズの回避。 万が一ZRAMも1GBスワップも限界に達した際、カーネルが「どのプロセスを殺すか」を重い処理で探索するのをやめ、「今メモリを要求したタスク」を即座に強制終了(Kill)してシステム全体のハングアップを防ぐ。 |
| カーネル | vm.panic_on_oom | 0 | システム巻き込み防止。 メモリ枯渇(OOM)が発生しても、カーネルパニックを起こしてシステムを強制再起動・完全フリーズさせず、OS全体の生存を最優先する。 |
X11のフレームバッファ設定
/etc/X11/xorg.confに追加
Section “Device”セクションの中に、以下の表を追加してみました。
Option "ShadowFB" "false"このオプションは、
/etc/X11/xorg.conf 内の Option “ShadowFB” は、画面の描画内容をグラフィックカード(VRAM)に直接書き込まず、メインメモリ(RAM)上の「シャドウ・フレームバッファ(影の領域)」に一度描画してから、まとめてVRAMへ転送する機能です。
高性能なGPUを使っている場合は不要(または無効化すべき)ですが、画面表示が極端に重い古い環境や組み込み環境で汎用ドライバーを使っている場合は、有効にすることで表示が滑らかになる選択肢です。
通常は有効になっていますが、
これを無効にして確かめてみました。
sudo vi /etc/X11/xorg.conf
Section "Device"
Identifier "device"
Driver "fbdev"
Option "ShadowFB" "false"
EndSection
Section "Screen"
Identifier "screen"
Device "device"
EndSection
この変更を行った後で、
一度jWMを終了し、再度jwmを起動して下さい(X11の再起動)
すると、以下のグラフィック系ベンチマークが上がりました
testsprite2 (SDL2のテストプログラム)
ShadowFB True 32
ShadowFB False 43
testdraw2 (SDL2のテストプログラム)
ShadowFB True 24
ShadowFB False 30
glxgears (OPENGL系グラフィックベンチメーク)
ShadowFB True 3
ShadowFB False 3
数値(おそらくFPS:1秒あたりのフレーム数)を見ると、一般的なLinux環境とは真逆で、Brainuxにおいては ShadowFB False(無効)の方がパフォーマンスが良い(フレーム数が高い)という結果になっていました。
なぜ Brainux で ShadowFB False の方が速いのか、この結果から推測すると、
- メインメモリ(RAM)とVRAMの「物理的な同一性」
PCなどの独立したグラフィックボードがある環境では「遅いVRAM」と「速いメインメモリ」が分かれているため、ShadowFB が有効に働きます。
しかし、BrainのSoC(i.MX28)はメインメモリの一部をVRAMとして共有(シェア)している、または極めて近いバスで直結されています。そのため、「メインメモリ上にシャドウバッファを作って、そこからVRAMにコピーする」という ShadowFB True の挙動は、「同じメモリ内でデータを2度転送しているだけ(無駄なオーバーヘッド)」になっている可能性が高いです。
- CPU(ARM926EJ-S)の処理能力の限界
i.MX28のCPUは、2026年の基準から見ると非常に低クロック(約454MHz)かつシングルコアです。
ShadowFB True にすると、メインメモリから実際のフレームバッファへ画面を「コピー(転送)する処理」をCPUが純粋にソフトウェア的に処理しなければなりません。このメモリ転送負荷(Memcpy)が、非力なCPUの大きな重荷になり、FPS低下(32→24、43→30)を招いています。
- glxgears がどちらも 3 FPS で変わらない理由
glxgears はOpenGL(3D)のテストですが、Brainuxにはハードウェア3Dアクセラレータがないため、すべてCPUで計算(ソフトウェアラスタライズ:Mesa/LLVMpipeなど)しています。
ここでは「3Dの計算(CPU処理)」があまりにも重すぎる(1秒間に3回計算するのが限界)ため、その後のメモリ転送方法が True だろうが False だろうが、結果に全く影響を与えていない(3D計算自体が完全に足を引っ張っている)状態です。
SDL2とSDL 1.2の内部挙動の違い、およびBrainuxにおける影響は以下の通りです。
- SDL 1.2 と SDL2 の大きな違い
- SDL 1.2 (古い仕様):
基本的にすべてソフトウェア(CPU)でピクセルを計算し、システムメモリ上のバッファ(サーフェス)に描画します。ハードウェアによる描画支援(アクセラレーション)をほとんど使いません。 - SDL2 (新しい仕様):
内部でOpenGLやOpenGLES、XRenderなどのハードウェアによる描画(GPUアクセラレーション)を利用する設計が標準になっています。
- なぜSDL 1.2でも ShadowFB False が正解なのか?
SDL 1.2はもともと「CPUで処理してメモリに書く」という動きをします。
- ShadowFB True の場合:
「SDL1.2がCPUでメインメモリに描画する」 ➔ 「X11がそれをさらに別のシャドウバッファ(メインメモリ)にコピーする」 ➔ 「最終的に実際の液晶のフレームバッファ(メモリ)に転送される」
という、メモリ内での三重のコピー(無駄なオーバーヘッド)が発生してしまいます。 - ShadowFB False の場合:
SDL 1.2が描画した内容が、余計なクッションを挟まずに液晶のフレームバッファへダイレクトに転送されるため、非力なBrainのCPU負荷を最小限に抑えられます。
また、X11上で、SDL1.2ベースのアプリを動かす場合には、
追加で、以下の設定も効果があるようです。
export SDL_VIDEO_X11_NODIRECTCOLOR=1環境変数 SDL_VIDEO_X11_NODIRECTCOLOR=1 は、SDL 1.2 が XWindow System(X11)環境で画面を描画する際、カラーマップ(色情報の管理方式)の自動作成を無効化し、システムのデフォルト設定を強制的に使わせるための設定です。
一言で言うと、「色の管理をサボらせて、描画の処理を軽くする(エラーを防ぐ)」設定です。
SDL 1.2 は古いライブラリであるため、画面を表示するときに「この画面は何色(何ビットカラー)で描画するか」を厳密に制御しようとします。
- 指定しない場合(通常動作):
SDL 1.2 は描画時に、より正確な色再現を行おうとして、X11 側に対して独自の「DirectColor(または PseudoColor)」というカラーマップ(色見本帳のようなもの)を新しく作ろうと要求します。 - NODIRECTCOLOR=1 を指定した場合:
独自のカラーマップ作成を明示的に禁止します。代わりに、Linux デスクトップ(X11)が元々使っているデフォルトの画面色設定(通常は 16bit や 24bit TrueColor)をそのまま使い回します。
Brainux におけるメリット
- 無駄な色変換処理の削減(軽量化)
Brain の非力な CPU 環境において、独自のカラーマップを計算・適用する処理はオーバーヘッドになります。これを無効化し、システムのデフォルトに「お任せ」することで、画面描画にかかる余計な CPU 負荷を減らすことができます。 - 画面の「色化け」や「チラつき」の防止
古い SDL アプリを X11 上で動かすと、アプリを起動した瞬間に画面全体の色が反転したり、サイケデリックな色合いに変色したり(カラーマップのバッティング)、最悪の場合は画面が正常に表示されずクラッシュすることがあります。この環境変数は、そうした色管理の衝突を防ぎ、安定して表示させるためのおまじないとして機能します。
いったん、~/.xprofileに以下の行を追加していきます。
export SDL_VIDEO_X11_NODIRECTCOLOR=1
この設定を変更しても、特に画面描画には問題ないように見えますので、
いったんこの設定で運用してみたいと思います。
参考:
その他環境編集オプションが、速度にどれだけかかわるかも確認してみました。
export GALLIUM_DRIVER=”” 変わらない(29)
export SDL_VIDEO_GL_DRIVER=”” 変わらない(29)
export vblank_mode=0 1のほうが早い
export SDL_RENDER_DRIVER=software 遅くなる(26)
export SDL_HINT_RENDER_DRIVER=software 遅くなる(28)
export SDL_RENDER_VSYNC=0 変わらない(29)
#export LIBGL_ALWAYS_SOFTWARE=1 遅くなる(28)
#export LP_NUM_THREADS=1 速くなる(時々30超える)
Views: 0