レコードの読み取り/準備に 15 マイクロ秒かかる場合、最大スループットは約 1 秒/15 マイクロ秒 = 67k/秒になります。ファイルを読み取る単一のスレッドがそれ以上のレコードを生成できないため、6uSec の部分は無視できます。(試してみて、プログラムを読み取り/処理のみに変更し、出力を破棄します)どうやって9uSを取得したのかわかりません。
これを 67k/sec を超えて飛ばすには ...
A) フォーマットするディスクから読み取ることができる 1 秒あたりの最大レコード数を見積もります。これはハードウェアに大きく依存しますが、平均的なラップトップでは 20Mb/秒の数値が一般的です。この数値は、目標とする上限を示しており、近づくにつれて、挑戦をやめることができます。
B)ファイルを読み取るためだけに単一のスレッドを作成し、IO 遅延を発生させます。このスレッドは、事前に割り当てられた大きなバッファ (それぞれ 4Mb など) に書き込む必要があります。これらを管理する方法については、http://en.wikipedia.org/wiki/Circular_bufferを参照してください。バッファごとにおそらく1000レコードを保持しようとしています(推測ですが、8つのレコードだけではありません!)疑似コード:
while not EOF
Allocate big buffer
While not EOF and not buffer full
Read file using fgets() or whatever
Apply only very small preprocessing, ideally none
Save into buffer
Release buffer for other threads
C)別のスレッド(レコードの順序が重要でない場合は複数)を作成して、リングバッファがいっぱいになったときに処理します。正規表現のステップです。このスレッドは、出力リング バッファーの別のセットに順番に書き込みます (ヒント、メモリ内でリング バッファー制御構造を分離しておいてください)。
While run-program
Wait/get an input buffer to process, semaphores/mutex/whatever you prefer
Allocate output buffer
Process records from input buffer,
Place result in output buffer
Release output buffer for next thread
Release input buffer for reading thread
D)データを消費する最終スレッドを作成します。この出力がディスクに書き込まれているのか、ネットワークに書き込まれているのかは明確ではないため、ディスク読み取りスレッドに影響を与える可能性があります。
Wait/get input buffer from processed records pool
Output records to wherever
Return buffer to processed records pool
ノート。すべてのバッファを事前に割り当て、元の場所に戻します。たとえば、ファイル読み取りスレッドと処理スレッドの間に 4 つのバッファーがあり、4 つすべてが注入されている場合、ファイル リーダーは 1 つが解放されるのを待ち、新しいバッファーを割り当てるだけではありません。回避できる場合は memset() バッファを使用しないようにしてください。メモリ帯域幅が無駄になります。多くのバッファーは必要ありませんよね、6? リングバッファごと?
システムは最も遅いスレッド ( http://en.wikipedia.org/wiki/Theory_of_constraints )に自動調整されるため、データを出力するよりも速く読み取って準備できる場合、すべてのバッファーがいっぱいになり、例外を除いてすべてが一時停止します。出力。
スレッドは同期点ごとに妥当な量のデータを渡しているため、このオーバーヘッドはそれほど重要ではありません。
上記の設計は、私のコードの一部が CSV ファイルをできるだけ速く読み取る方法です。基本的に、制限要因として入力 IO 帯域幅がすべてになります。