-1

非常に大きな配列の要素を合計するプログラムがあります。この合計を並列化したい。

#define N = some_very_large_no; // say 1e12
float x[N]; // read from a file
float sum=0.0;
main()
{

for (i=0, i<N, i++)

sum=sum+x[i];

}

スレッドを使用してこの合計を並列化するにはどうすればよいですか (c/c++/Java の任意のコード例で問題ありません)。マシンに 8 つのコアがある場合、最適なパフォーマンスを得るにはいくつのスレッドを使用する必要がありますか?

編集: N は非常に大きく (実際には 1e6 より大きい)、データを読み取ったファイルのサイズによって異なります。ファイルは GB の順序になっています。

編集:Nが大きな値に変更されます(1e12から1e16)

4

7 に答える 7

3

Javaで書くことができます

int cpus = Runtime.getRuntime().availableProcessors();
// would keep this of other tasks as well.
ExecutorService service = Executors.newFixedThreadPool(cpus);

float[] floats = new float[N];

List<Future<Double>> tasks = new ArrayList<>();
int blockSize = (floats.length + cpus - 1) / cpus;
for (int i=0, i < floats.length, i++) {
    final start = blockSize * i;
    final end = Math.min(blockSize * (i+1), floats.length);
    tasks.add(service.submit(new Callable<Double>() {
        public Double call() {
            double d= 0;
            for(int j=start;j<end;j++)
                d += floats[j];
            return d;
        }
     });
}
double sum = 0;
for(Future<Double> task: tasks)
    sum += task.get();

WhozCraig が言及しているように、複数のスレッドを必要とするのに 100 万個のフロートでは不十分である可能性が高いか、メイン メモリ (単一のスレッド化されたリソース) から配列をどれだけ速くロードできるかがボトル ネックであることがわかる可能性があります。データを取得するコストを含めるまでに高速になるとは想定できません。

于 2013-04-29T06:36:56.013 に答える
2

多くのスレッド(コア以上)を使用できます。しかし、スレッドとそのパフォーマンスは、それらがどのように機能しているかとして、アルゴリズムに依存しません。配列の長さが 100000 であるため、x スレッドを作成し、それぞれが arr[x] から arr[x+limit] を計算します。他のスレッドと重複しないように制限を設定する必要があり、要素が未使用のままにならないようにする必要があります。スレッドの作成:

   pthread_t tid[COUNT];
    int i = 0;
        int err;
        while (i < COUNT) 
        {
            void *arg;
            arg = x; //pass here a no which will tell from where this thread will use arr[x]
            err = pthread_create(&(tid[i]), NULL, &doSomeThing, arg);
            if (err != 0)
                printf("\ncan't create thread :[%s]", strerror(err));
            else
            {
                //printf("\n Thread created successfully\n");
            }

            i++;
        }
       // NOW CALCULATE....
        for (int i = 0; i < COUNT; i++) 
        {
            pthread_join(tid[i], NULL);
        }
}

void* doSomeThing(void *arg) 
{
    int *x;
    x = (int *) (arg);
   // now use this x to start the array sum from arr[x] to ur limit which should not overlap to other thread
}
于 2013-04-29T06:29:58.387 に答える