ハードウェア/実装は、アルゴリズムの時間/空間の複雑さに影響しますか?


32

私はCSの学生でもないので、これはばかげた質問かもしれませんが、どうか私に耐えてください...

プレコンピューター時代では、引き出しの配列のようなものでのみ配列データ構造を実装できます。値を抽出する前に、対応するインデックスでドロワーを見つける必要があるため、配列検索の時間の複雑さはバイナリ検索を想定。O(log(n))

しかし、コンピューターの発明は大きな違いをもたらしました。最近のコンピューターはRAMから非常に高速に読み取ることができるため、配列ルックアップの時間の複雑さはと考えています(技術的にはそうではありません。O(1)

別の例は、Python辞書です。誤って記述されたオーバーロードマジックメソッド(または、途方もなく不運、つまり、多くのハッシュ衝突を伴うキーで辞書アクセスの複雑さを得るかもしれませんが、通常はと推定されます。この場合、時間の複雑さは、Python辞書のハッシュテーブル実装と、ハッシュ関数のキーの実装の両方に依存します。O(n)__hash__O(1)

これは、ハードウェア/実装がアルゴリズムの時間の複雑さに影響する可能性があることを意味しますか?(両方の例はアルゴリズムではなくデータ構造に関するものですが、後者は前者に基づいて構築されており、データ構造の時間の複雑さを聞いたことがないため、ここでは「アルゴリズム」という用語を使用しています)

私にとって、アルゴリズムは抽象的かつ概念的であり、時間/空間の複雑さなどの特性は、特定の方法で実装されているかどうかによって影響されるべきではありませんが、そうですか?


コメントは詳細なディスカッション用ではありません。この会話はチャットに移動さました
ジル 'SO-悪であるのをやめる'

回答:


42

はい。確かに。不快感を和らげる方法は次のとおりです。

アルゴリズムの実行時間を分析するときは、特定の計算モデルに関して実行します。計算モデルは、各基本操作の実行にかかる時間などを指定します(配列ルックアップは時間ですか、時間ですか?)。アルゴリズムの実行時間は、計算のモデルに依存する場合があります。O(lognO1

計算のモデルを選択すると、アルゴリズムの分析は、ハードウェアに依存しなくなった、純粋に抽象的で概念的な数学的演習になります。

ただし、実際には、通常、ハードウェアの現実を反映した計算のモデルを選択します(少なくともある程度は)。そのため、ハードウェアが変更された場合、新しいハードウェアにより適した異なる計算モデルでアルゴリズムを分析することを決定できます。これが、ハードウェアが実行時間に影響を与える方法です。

これが非自明である理由は、入門クラスでは、計算のモデルについて話さないことが多いためです。明示的にすることなく、暗黙的にいくつかの仮定を行います。それは教育的な目的のために合理的ですが、それはコストがかかります-それは分析のこの側面を隠します。わかった。


あなたが言ったように、計算のモデルとしてランダムアクセスモデルを使用しますが、特定の計算にGPUを使用すると、SIMD命令を使用するため、一部のアルゴリズムの時間の複雑さが変わります。
ディープジョシ

6
また、O()表記は上限であることに注意してください。引き出しのアナロジーを使用して、限られたサイズ(実際のメモリのサイズに制限がある)の引き出しを見つける場合でも、構築にはO(1)時間かかります。20分間がメモリにアクセスするための隠された定数であるため、最も遠い引き出しに到達するのに20分かかっても(すべてのキャッシュミスで、スワップからデータをロードする必要さえあります)、まだO(1)時間です。
ゴスウィンフォンブレダロー

2
O(1)O(n

1
@CortAmmon:大規模な配列であっても、検索対象の要素の一部を除くすべてが開始点に非常に近い場合、ハッシュマップを使用するよりも線形検索を使用した方が高速になる場合があります。たとえば、要素の50%が最初の要素に一致し、25%が2番目に一致し、12.5%が3番目に一致する場合など、1つの奇数ボール要素が配列内のどこかにあるものに一致する場合を除き、予想される比較数サイズNのリストでMルックアップを実行すると、2M + Nになります。
-supercat

5
@DeepJoshi SIMD命令は、アルゴリズムの複雑さを変更しません。乗法定数のみを変更します。
ジル 'SO-悪であるのをやめる'

5

この質問には根本的な誤解があると思います。並べ替えられたリスト(たとえば、本の特定のページに番号が与えられている)でオブジェクトを見つけている人と、配列からアイテムを検索しているコンピューターを比較します。

O(logn)O(1)

そのため、DWが説明しているように、ハードウェア(つまり、計算のモデル)はアルゴリズムの実行時間に影響しますが、それはあなたの配列アクセスの例が基づいているようではありません。


2
公平を期すために、「メモリコントローラーがアドレスワイヤの電圧を17のバイナリ表現に設定する」と「データが戻る」間のすべての部分をスキップしました。それらの断片の1つ、ほぼ確実にOPによって記述される種類のバイナリ検索ツリーです。ただし、すべてのnについてlog nは約64であるため、一定時間で実行されます
Quuxplusone

@Quuxplusoneメモリのどの部分がバイナリ検索を使用しますか?アドレスラインはメモリセルを直接選択します。
デビッドリチャービー

私たちは自分の専門分野をはるかに超えて運営していますが、私が示唆しようとしているのは、アドレスデコーダデマルチプレクサのツリーの観点から実装されるということです。(キャッシュに伴う余分な複雑さを無視して、物理メモリに直接アクセスしていると仮定します。)繰り返しますが、この余分な複雑さはすべてO(lg size-of-memory)、つまり無視できるだけです。しかし、それはまさにOPが求めていたビットです!
Quuxplusone

2

いいえ、ハードウェアはアルゴリズムの複雑さに影響しません。

しかし、それはアルゴリズムの選択に影響を及ぼし、複雑性分析の有用性に影響を及ぼし、分析がほとんど意味をなさない(または単に学術的関心の対象となる)こともあります。

(配列要素へのアクセスとして)正しい引き出しを見つけるには、「線形検索」または「バイナリ検索を行う」アルゴリズムではなく、「インデックスによってN番目の要素を直接開く」アルゴリズムを使用します。アルゴリズムは変更されませんが、選択は変更されます。

一方、複雑さの分析自体、またはむしろその意義は、ハードウェアの影響を大きく受けます。

複雑性分析によって恒星である多くのアルゴリズムは、パフォーマンスが低いか、実際には役に立たないことがあります。これは、重要でない定数因子がまったく重要ではなく、支配的だからです。

または、かつては真であった(またはほとんど真であった)仮定はもはや成り立たないためです。たとえば、すべての操作はほとんど同じであるか(重要でない小さな一定の違いのみ)、またはどのメモリ位置にどの順序でアクセスしても違いはありません。複雑さの分析により、あるアルゴリズムは非常に多くの操作しか必要としないため、非常に優れていると結論付けることができます。実際には、各操作が保証されたキャッシュミス(またはさらに悪いことにページフォールト)を引き起こすことがあります。これにより、kは非常に大きくなり、重要ではなくなりますが、すべてを支配します。
アルゴリズムAが特定のサイズのデータ​​セットを処理するために500の操作を行い、アルゴリズムBが5だけであるが、Bがそれぞれ2,000万サイクルを燃やす5つのフォールトを引き起こす場合、分析または常識からわかるように、Aの方が優れています。

これは、例えば数年前のカッコウハッシングのような面白い驚きにつながりました。[利点の長いリスト]のおかげで非常に優れていました。誇大広告が冷めた後、すべてのアクセスで2つのキャッシュミス(より大きなデータセットの場合)が保証されたため、非常に劣っていたことが判明しました。

データのサブセットの識別と処理についても同様のことが起こりました。多くの場合、正しい解決策は次のとおりです。「すべてを実行する」、つまり、必要なことを把握して実行する代わりに、必要なデータセットの半分だけを直線的に処理します。信じられないかもしれませんが、ブランチの予測ミス、キャッシュミス、ページフォールトがないため、高速です。
3MBファイルの最初の8kBと最後の3kBを読む必要がありますか?さて、完全なファイルを読んで、望まないものを捨ててください。なぜなら、その間のシークは完全なものを読むよりも10倍遅くなるからです。

対数の複雑さがあるため、マップを使用しますか?または、アクセス時間が一定のハッシュテーブルですか?絶え間ない音。さて、1000個程度(ハードウェア、データサイズ、アクセスパターンに依存する)未満のものについては、線形検索の方が優れている場合もあります。驚き。

したがって、影響を受けるのはアルゴリズム自体ではなく、その有用性と選択です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.