2011-02-07 17 views
1

私はcharの2つの配列を持ち、各位置は1または0です。 2つの配列は異なるプロセスで計算され、結合されるマスターに送り返されるので、各配列はそれらのアレイ:Cでバイト配列をマージする最も効率的な方法は何ですか?

P1:[0、0、0、0、1、1、0、1]

P2:[1、0、1、1、0、0、0、0]

目標:[1,0,1,1,1,1,0]

しかし、これらは非常に大きなアレイである可能性があります。そのうちの1つをループするだけでなく、これを実行する超高速方法がありますか?

明確にするために、それらはORされるべきです。

+1

あなたがしなければならないのhttp://stackoverflow.com/questions/668280/whats-the-most-efficient-way-to-make-bitwise-operations-in-ac-array –

+1

を見てみましょう0と1をcharとして送信しますか?ビットを整数にパックしてからそれらをマスターに送ることができますか?次に、マスターの2つの整数をxorだけにすることができます。 – Makis

+0

@Makis、これはきちんとしたマイクロ最適化ですが、連続した範囲であれば、大規模な範囲では全く役に立たないでしょう。無駄な 'x^0'と' 0^x操作。各プロセスのビットがインターリーブされていれば良い考えです。 – bdonlan

答えて

2

バイト粒度と仮定すると十分に良いですが、あなたはおそらく、出力配列にコピーするmemcpyを使用したいと思います:

memcpy(goal, p2, 4); 
memcpy(goal + 4, p1 + 4, 4); 

あなたは、さらに唯一の自分の範囲を含んでp1p2をさせることによって、これを最適化することができ、例:

char p1[4] = { 1, 1, 0, 1 }; 
char p2[4] = { 1, 0, 1, 1 }; 
char goal[8]; 
memcpy(goal, p2, 4); 
memcpy(goal + 4, p1, 4); 

ビットベクトルパッキング - 各チャンクに8ビットをパックする場合もあります。これにより、アクセスが複雑になりますが、大規模な配列に対しては大量のメモリが節約されます。

+0

私はこのようにすることができるかもしれませんが、私のための次のステップは、ワーカーをマスターに送る前に、それらのプロセッサを組み合わせることになります。 1つの大きな割り当てとは対照的に、いくつかの小さな時間を再割り当てするためのオーバーヘッドがありますか? – amcashcow

+0

はい、オーバーヘッドが発生します。共有メモリを使用して、最終的な目標配列に書き込むことをお勧めします。 – bdonlan

+0

プロセッサが複数のマシンに分散されている場合はありません。P – amcashcow

0

は私が示唆している:これは本当にボトルネックであることを確認するプロファイリング

  1. バイト配列を整列してから、通常の線形ループを使用して、おそらくunsigned long longとしてアクセスすることによって、単一のマシン操作を使用してできるだけ多くのバイトを処理することで調べてください。
  2. 子プロセスが、おそらく何らかのランレングス圧縮を使用して、より効率的な形式でレポートするように並べ替えます。
0

あなたが異なるプロセッサ上で作業している場合は、おそらくあなたは縮小操作でMPIライブラリを使用して検討する必要がありますが、異なるスレッドを使用している場合、それは

MPI_Reduce(p, goal, size, MPI_CHAR, MPI_LOR, goal_process_id, MPI_COMM_WORLD); 

非常に高速で、その後、OpenMPの用語でも良いです

#pragma omp parallel for reduction(|, out) 
for(int i=0; i<size; i++) 
    out[i] = p1[i] * p2[i]; 
0

配列が使用されている理由があります:コードの単純さ(これは、迅速かつ汚いコードですか)?速度とメモリ消費の両面で最も効率的な方法は、実際にバイトレベルで動作することは間違いありません。配列を不用意に前後に振るのではなく、

おそらくこのようなものでしょうか?

uint8 proc_n (void) 
{ 
    uint8 result = 0x00; 
    uint8 i; 

    for(i=0; i<8; i++) 
    { 
    if(something) 
    { 
     result |= (0x01 << i); 
    } 
    } 

    return result; 
} 



typedef uint8 (*Proc_ptr)(void); 

Proc_ptr proc_array [PROCESSES] = 
{ 
    proc_1, 
    proc_2, 
    ... 
}; 

uint8 result = 0x00; 

for(i=0; i<PROCESSES; i++) 
{ 
    result |= proc_array[i](); 
}