2026年10月31日土曜日

インクリメンタル アクセスとデクリメンタルアクセス

データ構造を作り直すことにしました。ついては、アクセス方法の違いについて聞きました。 

インクリメンタル アクセスとデクリメンタルアクセスで、キャッシュヒット特性に差はありますか?

インクリメンタルアクセス(アドレスが順方向に増加)とデクリメンタルアクセス(アドレスが逆方向に減少)では、キャッシュヒット特性に明らかな差が出ることがあります。
この差は主に、現代のプロセッサに搭載されているハードウェアプリフェッチャ(事前読み込み機能)の挙動や設計に起因します。
主な違いと特性は以下の通りです。

1. ハードウェアプリフェッチャの対応度
現代のCPUは、次にアクセスされるデータを予測してキャッシュに先読みします。
  • インクリメンタル(順方向):
    • ほぼすべてのプロセッサのプリフェッチャが完璧に対応しています。
    • 連続的な順方向アクセス(A, A+1, A+2...)を検出すると、自動的に先読みが行われるため、キャッシュヒット率は非常に高くなります。
  • デクリメンタル(逆方向):
    • 多くの近代的なCPU(IntelやAMD、ARMの高性能コアなど)は逆方向のストライド(A, A-1, A-2...)も検出できます。
    • しかし、古いアーキテクチャや、低消費電力向けの簡易なプロセッサ(一部の組み込み向けコアなど)では、逆方向のプリフェッチに対応していない、あるいは順方向に比べて検出の優先度が低い場合があります。この場合、デクリメンタルアクセスではキャッシュミスが多発します。

2. 空間局所性とキャッシュラインのマッピング
メモリは「キャッシュライン(一般的に64バイト)」という単位でキャッシュに読み込まれます。
  • インクリメンタル:
    • キャッシュラインの先頭(オフセット0)から末尾に向かってアクセスが進むため、1度のキャッシュミスで読み込んだラインをフルに活用できます。
  • デクリメンタル:
    • キャッシュラインの末尾から先頭に向かって逆順にアクセスします。
    • プリフェッチが効かない環境では、「新しいキャッシュラインにまたがった瞬間(境界を越えたとき)」に必ずキャッシュミス(レイテンシ)が発生し、その後そのラインの残りのデータを逆向けに消化していく形になります。データの利用効率自体は同じですが、ミスの発生するタイミングやプリフェッチの起動タイミングが狂いやすくなります。

まとめ(比較表)
特性インクリメンタルアクセス (順方向)デクリメンタルアクセス (逆方向)
一般的なヒット率非常に高い(安定)高〜中(CPUのプリフェッチ能力に依存)
ハードウェア先読み確実に動作するCPUによっては動作しない・遅れる場合がある
不利益を被る環境特になし古いCPU、組み込み向けCPU、GPUの一部など
結論として:
最新のPCやサーバー向けCPUであれば、どちらも高いヒット率を維持できるよう設計されていますが、ハードウェアの最適化は常に「インクリメンタル(順方向)」を最優先に設計されているため、迷った場合はインクリメンタルなアクセス経路(例:多次元配列をループさせる際の順序など)を選択するのが安全です。

2026年10月30日金曜日

なぜ、ナーススケジューリング問題では、絶対指標ベンチマークへの言及がないか?

 VRP等の新しい論文では、各ベンチマークの言及が必ずあると思いますが、最近のナーススケジューリング問題の論文では、ないのが不思議です。以下は、AIの回答ですが、本当の理由は別なところにあると思います。


ナーススケジューリング問題(NSP: Nurse Scheduling Problem、またはNRP: Nurse Rostering Problem)の最近の論文で、VRP(車両ルーティング問題)のような「統一された絶対的な標準ベンチマーク」への言及や共通データでの比較が少なく見えるのは、研究者の間でもよく指摘される非常に鋭い着眼点です。
VRPではCVRPTWやGehring & Hombergerなどの決定版ベンチマークが存在し、全員が同じ土俵で競いますが、ナーススケジューリング問題でそれが難しいのには、この問題特有の背景や構造的な要因があります。
主な理由は以下の4点に集約されます。
1. 法規制や現場ルールが「国・病院ごとに違いすぎる」
VRPは「容量制限」や「時間枠」など、物理的・数学的にモデルを標準化しやすい特徴があります。しかし、ナーススケジューリングは「人間(労働者)」を対象としているため、制約が極めてローカルかつ複雑です。
  • 国による法規制の違い: 週の最大労働時間、夜勤後のインターバル(休息時間)の法的義務などが国ごとに全く異なります。
  • 病院・病棟ごとのローカルルール: 「AさんとBさんは仲が悪いので同じシフトにしない」「この病棟はベテランを必ず1人配置する」といった、数式化しにくいソフト制約(Soft Constraints)が無限に存在します。
結果として、ある論文が提案した優れたアルゴリズムも、別のデータセット(別の国のルール)にはそのまま適用できないケースが多く、共通のベンチマークで横並び比較する意義が薄れてしまうのです。
2. インスタンス(問題データ)の寿命とプラットフォームの断絶
過去に国際コンペティションなどで標準ベンチマークが作られなかったわけではありません。
  • INRC (International Nurse Rostering Competition): 2010年(INRC2010)や2015年(INRC2015)に世界大会が開催され、標準データセットが公開されました。
  • 第一線での風化: VRPのベンチマークが何十年も使われ続けるのに対し、NSPのコンペデータは「制約が当時の特定のモデルに依存しすぎている」ため、新しい解法(例えば最新の深層強化学習やLLMベースのメタヒューリスティクス)を適用しようとすると、データのパースや制約の再現が非常に難しく、敬遠されがちです。
3. 近年の論文の関心が「実用性・動的対応」にシフトしている
最近のNSPの論文では、静的な標準データをいかに速く解くかよりも、「現実の運用で使えるか」に焦点が当たっています。
  • 動的・確率的アプローチ: 急な欠勤(看護師の体調不良)や患者数の変動に対応する「リロスタリング(再スケジューリング)」や「確率的プログラミング」の研究が増えています。
  • 独自データの使用: そのため、著者が所属する国の実際の病院から提供された「リアルだけど独自のデータセット」を使って評価を行う論文が多くなり、結果として共通のベンチマークへの言及が減っています。
4. 評価指標(目的関数)を統一できない
VRPの目的関数は基本的に「総移動距離の最小化」や「車両台数の最小化」であり、明確です。
一方、NSPでは「病院側のコスト最小化(超過勤務手当の削減)」と「看護師側の満足度最大化(希望休の反映)」という相反する多目的最適化になります。何を最優先(あるいはどう重み付け)するかは病院ごとに異なるため、あるベンチマークスコアで「勝利」したとしても、それが本当に優れたアルゴリズムなのかを測るのが本質的に難しいという問題があります。

💡 まとめると
VRPが「綺麗に舗装されたサーキットでタイムを競うレース」だとすれば、ナーススケジューリングは「病院ごとに地形が変わる泥道を走るラリー」のようなものです。そのため、最近の論文では共通ベンチマークのスコアよりも、「いかに複雑で現実的な制約の組み合わせを破綻させずに解けるか(表現力と柔軟性)」に重きが置かれているのが、ベンチマークへの言及が少なく見える最大の理由です。

2026年10月29日木曜日

ナーススケジューリング問題ソルバ

 2026年になっても、未だ色々な方式が提案されています。

<各ベンチマークについての言及がない>

ASPに基づく適応型優先度付き巨大近傍探索の実装とナーススケジューリング問題への適用
JSME-TJ
ナース・スケジューリングの論文、勤務表づくりに使える?|手組みゼロ



不思議なことに、アカデミックかつクラシカルなベンチマークがいくつもあるのに、それらに対しては、言及がありません。この傾向は、日本に限らず海外文献でも同様です。最近の論文流行は、AIを使った当該病棟でのモデル改善ですが、これは、モデリングの改善であって、ソルバ性能の改善ではありません。ソルバは、MIPソルバ、CP-SAT等、既存汎用ソルバ、であってソルバそのものの改善でないことが多いです。いずれにせよ、共通インスタンスでのベンチマークについて言及がないので、実際のところ、どの程度の有効性があるのか分かりません。アカデミックベンチマークは、問題規模が段階的に揃っているので、問題規模に対する有効性の評価も出来ます。日本とEUでは、そもそも働きかたそのものが違うので比較にならない、と考える方もいるかもしれませんが、私は、組み合わせ最適化能力と問題規模というパラメータのエッセンスは変わらないと考えています。

一部で、ナーススケジューリング問題は、最近のMIPソルバで解けるようになった、との指摘があるのですが、私の認識は、全然そんなことはありません。感覚的には、「MIPソルバでは、ほとんど解けない」、に近いです。(試しにINRC2問題をMIPソルバにやらせてみてください。ほとんど解けません。Scheduling Benchmarksについても解けるのはInstance-8/16/17位までです。) 

ベンチマーク問題と実務インスタンスで、主に違うのは、ペア制約の有無で、これが、インスタンスをより難しくする方向に作用します。また最近では、同数制約という運用で回避可能なはずの制約まで課されるようになってしまっていますが、これもより難しくする方向に作用します。

いずれにしても、骨格的には、アカデミックベンチマークインスタンスでも間違いはなく、実務ではさらに雑多な制約が入ることで、より難しくなる現実があります。


<まず第一に汎用ナーススケジューリング問題ソルバ>

ソルバが厳密解を容易に求められない以上、言い換えるならソルバ間で優劣差が存在する以上、最善を求めるのは当然ではないでしょうか?皆が同じ土俵上で、優劣差がない状態ならば、それ以上の最善は求められない、すなわち、組み合わせ最適化能力の向上を目指す必要がないことに同意します。しかし、現状は、スケジュールナースDVT版(開発版)から見て、「さらに優劣差が広がっている」、と推察します。

なので、汎用的なナーススケジューリング問題ソルバの開発がまず第一です。そのソルバは、アカデミックベンチマークについてほとんど全てインスタンスの厳密解を出力できることが必要要件です。これにより、基本的なナーススケジューリング問題についての組み合わせ最適化能力は担保されます。

皆さん、基本的ソルバの能力向上の必要性を無視されていますが、この問題に取り組んで十余年、私はづっとその必要性を切に感じていました。サポートをしていて、「これ以上は、物理限界で無理ですよ!」と言いたい場面が多々ありました。

<VRPとの違い>

ナーススケジューリング問題がVRPと異なるのは、管理者の多様な欲求を徒手選択するためのソフト制約にあると思っています。管理者が実現したいと思っている全てを実現出来る訳ではない、何かを取ろうとすれば、何かを捨てざるを得ないトレードオフを提供するところが、VRPと本質的に違うところだと思います。管理者の価値観は、管理者で違うので、職場毎に多種多様な制約、世界に一つしかないその職場にユニークな制約が生じます。しかし、最終的には、トレードオフに至るのが共通の帰結です。人の気持ちに寄り添うのがVRPとの決定的な違いとも言えますが、その結末は、いつもトレードオフになります。その際、管理者に納得してもらうのに必要なキーワードが「物理限界」です。

これ以上良い解はない、「物理限界です」という言い切りが出来ることが、管理者に納得して頂く最強で最終の切り札になります。その意味で、クローズドインスタンス環境にしても、物理限界、そして物理限界にどこまで近づけたかの指標であるLB-UB Gap位は、言及して頂けたら、と思います。大抵の場合、LB-UB GAPはゼロではないはずです。


物理限界に挑むナーススケジューリング問題に対する標準解法

https://schedule-nurse.blogspot.com/2026/05/blog-post_24.html

さらに、これを市井の様々なナーススケジューリング問題に適用させようということになると、汎用的フレームワークを再設計する必要があり、現在実装中、という訳です。

史上最大規模のナーススケジューリング問題が解けた、と言っても実務で遭遇するプロジェクトの厳密解がただちに求まる、ということではありません。依然として、何割かのプロジェクトの厳密解を求めることは難しいのでは?と感じています。それ位、実務で扱っている現実のナーススケジューリング問題を厳密に解くことは難しいものなのです。

<次にモデリング>

ソルバの改良が終わったのち、次に行うべきは、日本語指示によるモデリング方法の開発です。昨今、AIが特段に進化したので、それを利用します。問題は、そのモデリングが適切かどうかは、管理者が解を見ないと分からないので、GUIと連携しながら修正を加えていくスタイルが必須と考えています。プロジェクト作成サービスで、私が行っていることの代わりが出来ることが、究極の目標です。

<まとめ>

アカデミックベンチマークで性能を担保し、なおかつ日本語による指示モデリングで市井のナーススケジューリングの現場の諸問題をモデリングできるようにする、2段構えが究極のソルバである、と考えています。



2026年10月28日水曜日

コーディングの未来

 ビル・ゲイツ氏「AIが人間の雇用の大部分を代替…今後20年が最も混乱」(中央日報日本語版)|dメニューニュース(NTTドコモ)

ビル・ゲイツ氏でさせ敵わないと言わせる昨今のAI進化です。

実際、私も活用して本当だと思います。それでも、全体アーキテクチャ設計は、AIに渡してはいません。全体の中の部品設計においては、活用していますが、トータルを俯瞰した設計については、長い経験の方に未だ歩がある、と見ています。

そうした経験なしに、いきなりAIにコーディングさせることが効率的とは思いません。これから、新卒プログラマは、受難の時代を迎えるのではないでしょうか?

優秀なアーキテクトにとってAIは、優秀な部下を持ったことと同じです。機械的な作業は、AIに任せればよいのですから。少数のアーキテクトさえ居れば、巨大なプロジェクトも可能になる、と思います。

自分は、古き良き時代の、最後の世代になるのかもしれません。



2026年10月26日月曜日

unsigned char(8bit)× int16(16bit)のベクトル積

 unsigned charとint16のベクトル積のSSEコード

結論から言うと、unsigned char(8bit)× int16(16bit)のベクトル積を SSE2 で行うには、 「8bit → 16bit へのゼロ拡張」+「16bit × 16bit の乗算」 という 2 ステップ構成になります。

SSE2 には 8bit × 16bit の直接乗算命令は存在しないため、 unpack(ゼロ拡張)→ PMULLW(16bit multiply) が正解です。

最速の SSE2 コードを完成形で提示します。

🧩 unsigned char × int16 の SSE2 ベクトル積の正しい流れ

1. unsigned char(8bit)を 16bit にゼロ拡張

SSE2 の PUNPCKLBW / PUNPCKHBW を使う。

cpp
__m128i bytes = _mm_loadu_si128((__m128i*)uc);   // unsigned char × 16
__m128i zero  = _mm_setzero_si128();

// 下位8バイト → 16bit に拡張
__m128i uc_lo = _mm_unpacklo_epi8(bytes, zero);

// 上位8バイト → 16bit に拡張
__m128i uc_hi = _mm_unpackhi_epi8(bytes, zero);

これで:

  • uc_lo = 16bit × 8

  • uc_hi = 16bit × 8

に変換される。

2. int16 と 16bit × 16bit の乗算(PMULLW)

cpp
__m128i s16_lo = _mm_loadu_si128((__m128i*)i16);      // int16 × 8
__m128i s16_hi = _mm_loadu_si128((__m128i*)(i16 + 8)); // int16 × 8

// 16bit × 16bit の乗算(下位16bit)
__m128i prod_lo = _mm_mullo_epi16(uc_lo, s16_lo);
__m128i prod_hi = _mm_mullo_epi16(uc_hi, s16_hi);

_mm_mullo_epi16(PMULLW)は:

  • signed 16bit × signed 16bit → 下位 16bit を返す

unsigned char はゼロ拡張しているので signed として扱っても問題なし。

✔ 完成形:unsigned char × int16 の SSE2 ベクトル積コード

cpp
void mul_uc_i16_sse(const unsigned char* uc, const int16_t* s16,
                    int16_t* out)
{
    __m128i bytes = _mm_loadu_si128((__m128i*)uc);
    __m128i zero  = _mm_setzero_si128();

    // 8bit → 16bit ゼロ拡張
    __m128i uc_lo = _mm_unpacklo_epi8(bytes, zero);
    __m128i uc_hi = _mm_unpackhi_epi8(bytes, zero);

    // int16 をロード
    __m128i s16_lo = _mm_loadu_si128((__m128i*)s16);
    __m128i s16_hi = _mm_loadu_si128((__m128i*)(s16 + 8));

    // 16bit × 16bit の乗算
    __m128i prod_lo = _mm_mullo_epi16(uc_lo, s16_lo);
    __m128i prod_hi = _mm_mullo_epi16(uc_hi, s16_hi);

    // 結果をストア
    _mm_storeu_si128((__m128i*)out,     prod_lo);
    _mm_storeu_si128((__m128i*)(out+8), prod_hi);
}

2026年10月24日土曜日

飽和演算

unsigned char同士の演算で負の場合0になるSSE命令は?

結論だけ先に言うと、unsigned char(8bit)同士の演算で「負になったら 0 に飽和する」SSE 命令は存在します。 それは SSE2 の saturating subtract for unsigned bytes:

PSUBUSB(Packed SUBtract Unsigned Saturate Bytes) → 8bit の unsigned subtract で、結果が負になる場合 0 に飽和する。

🔍 なぜ PSUBUSB が該当するのか

SSE2 には「飽和演算(saturating arithmetic)」があり、特に unsigned byte に対しては:

  • PSUBUSB:a - b が負なら 0 に clamp

  • PADDUSB:a + b が 255 を超えたら 255 に clamp

あなたの質問は「unsigned char 同士の演算で負の場合 0 になる SSE 命令」なので、 まさに PSUBUSB がそのものです。

🧠 補足:Intel の saturating arithmetic の仕様

検索結果(Arm の saturating arithmetic の一般仕様)では:

unsigned saturating operation では、結果が negative なら 0 になる

と説明されています。 x86 SSE2 でも同じ概念があり、unsigned byte subtract の saturating 版が PSUBUSB です。

📌 使用例(C/C++ intrinsics)

cpp
#include <emmintrin.h>

__m128i a = _mm_set1_epi8(10);
__m128i b = _mm_set1_epi8(20);

// 10 - 20 = -10 → saturate to 0
__m128i r = _mm_subs_epu8(a, b);

_mm_subs_epu8 が PSUBUSB に対応します。

2026年10月20日火曜日

Q.登録マイクロソフトアカウント(買い切り版)の変更

Q.登録アドレス(買い切り版)ですが、県の規制があり、

 xxx@pref.xxxxxxx.lg.jp 

がうまくマイクロソフトアカウントに登録できないことがわかりました。

そこで、代替の

xxx@outlook.jp 

に登録の変更をお願いいたします。

こちらは、すでにマイクロソフトアカウントを取得済のアドレスになります。

Ans.

変更しました。明日には、有効になっている可能性が高いと思います。明日以降、お送りしたインストールマニュアルに従ってトライしてみてください。