0

以前に書いたコードがあります。その唯一の目的は、openMP の実験でした。しかし、最近、MacBook Pro Lion (2011 年初頭) から MacBook Pro Mountain Lion (2013 年初頭) に切り替えました。他の情報のハードウェアを入手するのに役立つ場合は、喜んで提供します。コードは古いもので問題なく動作しました。つまり、8 つのスレッドがプロセッサで 100% (最小 98%) の負荷を受けました。そして今、私の新しいマシンで再コンパイルされた同一のコードは、62% の最大プロセッサ負荷しか得られません。糸を上げても。プロセッサ負荷は両方とも「istat pro」で測定されます。

私の質問は、これが起こる原因は何ですか?

編集: for in を削除すると、問題は解決するようです#pragma omp parallel for shared(largest_factor, largest)。だから私は得ます#pragma omp parallel shared(largest_factor, largest) しかし、なぜそれが機能するのかまだわかりません。

問題のコード:

#include <stdio.h>
#include <omp.h>

double fib(double n);

int main()
{
    int data[] = {124847,194747,194747,194747,194747,
                  194747,194747,194747,194747,194747,194747};
    int largest, largest_factor = 0;



    omp_set_num_threads(8);
    /* "omp parallel for" turns the for loop multithreaded by making each thread
     * iterating only a part of the loop variable, in this case i; variables declared
     * as "shared" will be implicitly locked on access
     */
    #pragma omp parallel for shared(largest_factor, largest)
    for (int i = 0; i < 10; i++) {
            int p, n = data[i];

            for (p = 3; p * p <= n && n % p; p += 2);
            printf("\n%f\n\n",fib(i+40));
            if (p * p > n) p = n;
            if (p > largest_factor) {
                    largest_factor = p;
                    largest = n;
                    printf("thread %d: found larger: %d of %d\n", 
                            omp_get_thread_num(), p, n);
            } 
            else 
            {
                    printf("thread %d: not larger:   %d of %d\n", 
                           omp_get_thread_num(),     p, n);
            }
    }

    printf("Largest factor: %d of %d\n", largest_factor, largest);
    return 0;
} 

double fib(double n)
{ 
if (n<=1)
{
    return 1;
}
else
{
    return fib(n-1)+fib(n-2);
}
}
4

1 に答える 1

0

すべてのスレッドが使用されているとは限らない主な理由は、(再帰関数または内部ループのために) 各スレッドにかかる時間が異なり、反復が 10 回しかないためです。高速スレッドは高速で終了し、実行するスレッドはわずかしか残っていません。コードを最初に実行すると、100% から始まり、高速なスレッドが終了し、最後の低速なスレッドがまだいくつか実行されているため、低下します。反復を 100 に変更すると (そしてデータ配列を増やすと)、CPU 使用率が 100% でずっと長く表示されます。コードにタイミングの出力をいくつか追加しました。

また、共有変数で競合状態が発生していると思われるため、クリティカル セクションを追加しました。

「for」ステートメントのないコードに関する質問に答えるには、8 つの異なるスレッドで同じコードを実行していることになります。スレッドが特定の反復を実行する代わりに、それぞれが 10 回の反復すべてを実行します。これは、単一のスレッドを実行するよりも速くはなく、おそらくさらに遅くなります。

最後に、各反復には一般に異なる時間がかかるため、このように「スケジュール(動的)」を使用する必要があります

#pragma omp parallel for shared(largest_factor, largest) schedule(dynamic)

ただし、反復回数は 10 回しかないため、この場合は大きな違いはないと思います。何が起こっているのかを理解するために、コードに対して行ったことは次のとおりです。

#include <stdio.h>
#include <omp.h>

double fib(double n);

int main()
{
    int data[] = {124847,194747,194747,194747,194747,
                  194747,194747,194747,194747,194747,194747};
    int largest, largest_factor = 0;

    omp_set_num_threads(8);
    /* "omp parallel for" turns the for loop multithreaded by making each thread
     * iterating only a part of the loop variable, in this case i; variables declared
     * as "shared" will be implicitly locked on access
     */
    #pragma omp parallel for shared(largest_factor, largest)
    for (int i = 0; i < 10; i++) {
            int p, n = data[i];
        double time = omp_get_wtime();
        for (p = 3; p * p <= n && n % p; p += 2);
        printf("\n iteratnion %d, fib %f\n\n",i, fib(i+40));
        time = omp_get_wtime() - time;
        printf("time %f\n", time);

        if (p * p > n) p = n;
        #pragma omp critical
        {
           if (p > largest_factor) {        
              largest_factor = p;
              largest = n;      
              printf("thread %d: found larger: %d of %d\n", 
                    omp_get_thread_num(), p, n);
            } 
            else {
                printf("thread %d: not larger:   %d of %d\n", 
                        omp_get_thread_num(),     p, n);
            }
        }
    }

    printf("Largest factor: %d of %d\n", largest_factor, largest);
    return 0;
} 

double fib(double n) { 
if (n<=1) {
    return 1;
}
else {
    return fib(n-1)+fib(n-2);
}
}
于 2013-04-12T08:41:36.823 に答える