エラトステネスによる素数は同時実行よりも順次に速く生成されます
エラトステネスのふるいを使用して素数を効率的に生成したいですか?驚くべきことに、順次実装は同時実装よりもはるかに高速になる可能性があります。この記事では、同時バージョンの潜在的なボトルネックを調査し、逐次実装と同時実装の両方を最適化するためのヒントをいくつか提供します。
逐次実装
ふるいの逐次実装エラトステネスは簡単です:
- 最大数までのすべての値に対してブール値の配列を true に初期化します。
- 2 から最大数の平方根までの数値を反復処理します。
- 各数値 p について、ブール配列内の対応する値を false に設定して、p の倍数をすべて取り消し線で消します。
- まだ true に設定されている残りの数値を出力します。
このアプローチは比較的効率的で、時間計算量は O(n log log n) です。
同時実装
同時実装の目的は次のとおりです。外側のループを並列化して、2 から最大数の平方根までの数値を繰り返します。範囲を複数の小さなサブ範囲に分割し、各サブ範囲を異なるスレッドに割り当てることができます。各スレッドは、その部分範囲内の p の倍数を個別に取り消すことができます。
同時実装における潜在的なボトルネック
同時実装には、いくつかの潜在的なボトルネックがあります。
-
スレッド同期オーバーヘッド: 各スレッドは、共有ブール配列にアクセスして変更する必要があります。これには、複数のスレッドが同じ要素を同時に変更しようとしないようにするための同期プリミティブ (ロックやアトミック操作など) が必要です。特に配列が大きい場合、同期によって重大なオーバーヘッドが発生する可能性があります。
-
フォールス シェアリング: スレッドは、メモリ内で互いに近い配列のサブ範囲に割り当てられる場合があります。これにより、異なるスレッドが同じキャッシュ ラインに意図せずアクセスし、パフォーマンスが低下する誤った共有が発生する可能性があります。
-
制限された並列処理: 並列処理のレベルは、使用可能なプロセッサの数によって制限されます。最大数がプロセッサの数よりもそれほど大きくない場合、並列化の利点は最小限である可能性があります。
最適化のヒント
両方のシーケンシャルを最適化するには同時実装の場合は、次のヒントを考慮してください:
-
特殊なデータ構造を使用する: ブール配列を使用する代わりに、効率的な素数生成用に特別に設計されたビットセットまたは素数ふるいデータ構造を使用します。
- ループ制御の最適化: 順次実装では、ループ カウンター p の素因数で割り切れる数値のみをマークする、修正されたエラトステネスのふるいの使用を検討します。
-
同期オーバーヘッドの削減: 同時実装では、ロックフリー アルゴリズムやアトミック操作などのきめ細かい同期手法を使用して、共有データへのアクセスのオーバーヘッドを最小限に抑えます。
-
偽共有の削減:異なるスレッドに割り当てられたサブ範囲が個別のキャッシュ ラインに確実に格納されるようにするための追加メモリを含むブール配列。
-
並列処理の増加: 複数のプロセッサを使用するなど、並列処理のレベルを上げる方法を検討します。より多くのスレッドを持つスレッド プールを使用します。
結論
エラトステネスのふるいを同時に実装すると素数生成を高速化できる可能性がありますが、潜在的なボトルネックがあるため、逐次実装よりも常に高速であるとは限りません。これらのボトルネックに慎重に対処し、最適化手法を採用することで、順次実装と同時実装の両方のパフォーマンスを向上させることができます。
以上がエラトステネスの篩の同時実装は、逐次実装よりも常に高速ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。