Pertanyaan Cara mendapatkan 100% penggunaan CPU dari program C.


Ini pertanyaan yang cukup menarik jadi biarkan saya mengatur adegannya. Saya bekerja di The National Museum of Computing, dan kami baru saja mendapatkan komputer super Cray Y-MP EL dari tahun 1992, dan kami benar-benar ingin melihat seberapa cepat itu bisa berjalan!

Kami memutuskan cara terbaik untuk melakukan ini adalah menulis program C sederhana yang akan menghitung bilangan prima dan menunjukkan berapa lama waktu yang dibutuhkan untuk melakukannya, kemudian menjalankan program pada PC desktop modern cepat dan membandingkan hasilnya.

Kami dengan cepat menggunakan kode ini untuk menghitung bilangan prima:

#include <stdio.h>
#include <time.h>

void main() {
    clock_t start, end;
    double runTime;
    start = clock();
    int i, num = 1, primes = 0;

    while (num <= 1000) { 
        i = 2; 
        while (i <= num) { 
            if(num % i == 0)
                break;
            i++; 
        }
        if (i == num)
            primes++;

        system("clear");
        printf("%d prime numbers calculated\n",primes);
        num++;
    }

    end = clock();
    runTime = (end - start) / (double) CLOCKS_PER_SEC;
    printf("This machine calculated all %d prime numbers under 1000 in %g seconds\n", primes, runTime);
}

Yang pada laptop dual core kami menjalankan Ubuntu (The Cray menjalankan UNICOS), bekerja dengan sempurna, mendapatkan 100% penggunaan CPU dan memakan waktu sekitar 10 menit atau lebih. Ketika saya tiba di rumah, saya memutuskan untuk mencobanya pada PC gaming modern hex-core saya, dan disinilah kami mendapatkan edisi pertama kami.

Saya pertama kali mengadaptasi kode untuk berjalan di Windows karena itulah yang digunakan game PC, tetapi sedih untuk menemukan bahwa proses itu hanya mendapatkan sekitar 15% dari kekuatan CPU. Saya pikir itu harus Windows menjadi Windows, jadi saya boot ke CD Live Ubuntu berpikir bahwa Ubuntu akan memungkinkan proses untuk berjalan dengan potensi penuh seperti yang telah dilakukan sebelumnya di laptop saya.

Namun saya hanya mendapat 5% penggunaan! Jadi pertanyaan saya adalah, bagaimana saya bisa mengadaptasi program untuk dijalankan pada mesin game saya di Windows 7 atau Linux pada utilisasi CPU 100%? Hal lain yang akan menjadi besar tetapi tidak diperlukan adalah jika produk akhir bisa menjadi satu. Exe yang dapat dengan mudah didistribusikan dan dijalankan pada mesin Windows.

Terima kasih banyak!

P.S. Tentu saja program ini tidak benar-benar bekerja dengan prosesor khusus Crays 8, dan itu adalah masalah lain ... Jika Anda tahu apa-apa tentang mengoptimalkan kode untuk bekerja pada komputer super 90-an Cray, beri kami teriakan juga!


76
2018-02-11 22:11


asal


Jawaban:


Jika Anda menginginkan 100% CPU, Anda perlu menggunakan lebih dari 1 inti. Untuk melakukan itu, Anda memerlukan banyak utas.

Berikut ini versi paralel menggunakan OpenMP:

Saya harus meningkatkan batas untuk 1000000 untuk membuatnya lebih dari 1 detik di komputer saya.

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

int main() {
    double start, end;
    double runTime;
    start = omp_get_wtime();
    int num = 1,primes = 0;

    int limit = 1000000;

#pragma omp parallel for schedule(dynamic) reduction(+ : primes)
    for (num = 1; num <= limit; num++) { 
        int i = 2; 
        while(i <= num) { 
            if(num % i == 0)
                break;
            i++; 
        }
        if(i == num)
            primes++;
//      printf("%d prime numbers calculated\n",primes);
    }

    end = omp_get_wtime();
    runTime = end - start;
    printf("This machine calculated all %d prime numbers under %d in %g seconds\n",primes,limit,runTime);

    return 0;
}

Keluaran:

Mesin ini menghitung semua 78498 bilangan prima di bawah 10.000 dalam 29.753 detik

Inilah CPU 100% Anda:

enter image description here


80
2018-02-11 22:27



Anda menjalankan satu proses pada mesin multi-core - sehingga hanya berjalan pada satu inti.

Solusinya cukup mudah, karena Anda hanya mencoba untuk mematok prosesor - jika Anda memiliki N core, jalankan program Anda N kali (secara paralel, tentu saja).

Contoh

Berikut ini beberapa kode yang menjalankan program Anda NUM_OF_CORES kali secara paralel. Ini kode POSIXy - itu menggunakan fork - jadi Anda harus menjalankannya di Linux. Jika yang saya baca tentang Cray benar, mungkin lebih mudah untuk mem-port kode ini daripada kode OpenMP di jawaban lainnya.

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#define NUM_OF_CORES 8
#define MAX_PRIME 100000

void do_primes()
{
    unsigned long i, num, primes = 0;
    for (num = 1; num <= MAX_PRIME; ++num) {
        for (i = 2; (i <= num) && (num % i != 0); ++i);
        if (i == num)
            ++primes;
    }
    printf("Calculated %d primes.\n", primes);
}

int main(int argc, char ** argv)
{
    time_t start, end;
    time_t run_time;
    unsigned long i;
    pid_t pids[NUM_OF_CORES];

    /* start of test */
    start = time(NULL);
    for (i = 0; i < NUM_OF_CORES; ++i) {
        if (!(pids[i] = fork())) {
            do_primes();
            exit(0);
        }
        if (pids[i] < 0) {
            perror("Fork");
            exit(1);
        }
    }
    for (i = 0; i < NUM_OF_CORES; ++i) {
        waitpid(pids[i], NULL, 0);
    }
    end = time(NULL);
    run_time = (end - start);
    printf("This machine calculated all prime numbers under %d %d times "
           "in %d seconds\n", MAX_PRIME, NUM_OF_CORES, run_time);
    return 0;
}

Keluaran

$ ./primes 
Calculated 9592 primes.
Calculated 9592 primes.
Calculated 9592 primes.
Calculated 9592 primes.
Calculated 9592 primes.
Calculated 9592 primes.
Calculated 9592 primes.
Calculated 9592 primes.
This machine calculated all prime numbers under 100000 8 times in 8 seconds

23
2018-02-11 22:16



kami benar-benar ingin melihat seberapa cepat itu bisa terjadi!

Algoritme Anda untuk menghasilkan bilangan prima sangat tidak efisien. Bandingkan dengan primegen yang menghasilkan 50847534 bilangan prima hingga 1000000000 hanya dalam 8 detik pada Pentium II-350.

Untuk mengkonsumsi semua CPU dengan mudah Anda bisa memecahkan masalah paralel yang memalukan mis., hitung Set Mandelbrot atau gunakan pemrograman genetika untuk melukis Mona Lisa dalam beberapa utas (proses).

Pendekatan lain adalah dengan mengambil program benchmark yang sudah ada untuk superkomputer Cray dan port ke PC modern.


8
2018-02-11 23:06



Alasan Anda mendapatkan 15% pada prosesor hex core adalah karena kode Anda menggunakan 1 inti pada 100%. 100/6 = 16,67%, yang menggunakan rata-rata bergerak dengan penjadwalan proses (proses Anda akan berjalan di bawah prioritas normal) dapat dengan mudah dilaporkan sebesar 15%.

Oleh karena itu, untuk menggunakan 100% cpu, Anda harus menggunakan semua inti CPU Anda - luncurkan 6 jalur kode eksekusi paralel untuk CPU hex core dan miliki skala ini hingga ke banyak prosesor mesin Cray Anda memiliki :)


4
2018-02-11 22:25



Juga sangat sadar bagaimana Anda sedang memuat CPU. Sebuah CPU dapat melakukan banyak tugas yang berbeda, dan sementara banyak dari mereka akan dilaporkan sebagai "memuat CPU 100%" mereka masing-masing dapat menggunakan 100% dari berbagai bagian CPU. Dengan kata lain, sangat sulit untuk membandingkan dua CPU yang berbeda untuk kinerja, dan terutama dua arsitektur CPU yang berbeda. Melaksanakan tugas A dapat mendukung satu CPU di atas yang lain, sementara mengeksekusi tugas B dapat dengan mudah menjadi sebaliknya (karena kedua CPU mungkin memiliki sumber daya yang berbeda secara internal dan dapat mengeksekusi kode dengan sangat berbeda).

Ini adalah alasan mengapa perangkat lunak sama pentingnya untuk membuat komputer berfungsi optimal seperti perangkat keras. Ini memang benar untuk "superkomputer" juga.

Satu ukuran untuk kinerja CPU bisa menjadi instruksi per detik, tetapi sekali lagi instruksi tidak dibuat sama pada arsitektur CPU yang berbeda. Ukuran lain bisa berupa kinerja IO cache, tetapi infrastruktur cache tidak sama. Maka ukuran bisa menjadi jumlah instruksi per watt yang digunakan, seperti pengiriman daya dan disipasi sering menjadi faktor pembatas ketika mendesain komputer cluster.

Jadi pertanyaan pertama Anda seharusnya: Parameter kinerja mana yang penting bagi Anda? Apa yang ingin Anda ukur? Jika Anda ingin melihat mesin mana yang mendapat FPS paling banyak dari Quake 4, jawabannya mudah; rig permainan Anda akan, karena Cray tidak dapat menjalankan program itu sama sekali ;-)

Tepuk tangan, Steen


2
2018-04-29 07:56



Cobalah untuk memparalelkan program Anda menggunakan, mis., OpenMP. Ini adalah kerangka kerja yang sangat sederhana dan efektif untuk membuat program paralel.


0
2018-02-11 22:20



Untuk peningkatan cepat pada satu inti, hapus panggilan sistem untuk mengurangi perpindahan konteks. Hapus garis-garis ini:

system("clear");
printf("%d prime numbers calculated\n",primes);

Yang pertama sangat buruk, karena akan menelurkan proses baru setiap iterasi.


0
2018-02-15 23:09



Cukup mencoba untuk Zip dan Unzip file besar, tidak ada yang berat I / o operasi dapat menggunakan cpu.


0
2018-02-12 06:11