Apa arti istilah "terikat CPU" dan "terikat I / O"?

Jawaban:

452

Cukup intuitif:

Suatu program terikat CPU jika ia akan pergi lebih cepat jika CPU lebih cepat, yaitu menghabiskan sebagian besar waktunya hanya menggunakan CPU (melakukan perhitungan). Sebuah program yang menghitung angka baru π biasanya akan terikat dengan CPU, itu hanya angka-angka.

Suatu program terikat I / O jika akan berjalan lebih cepat jika subsistem I / O lebih cepat. Sistem I / O yang tepat yang dimaksud dapat bervariasi; Saya biasanya mengasosiasikannya dengan disk, tetapi tentu saja jaringan atau komunikasi secara umum juga umum. Sebuah program yang melihat melalui file besar untuk beberapa data mungkin menjadi I / O terikat, karena bottleneck adalah pembacaan data dari disk (sebenarnya, contoh ini mungkin agak kuno hari ini dengan ratusan MB / s datang dari SSD).

beristirahat
sumber
Bagaimana hal ini mengikat untuk memahami komunikasi HTTP pada perangkat seluler? Saya telah melihat lonjakan penggunaan CPU dari penggunaan operasi java.nio .
IgorGanapolsky
I / O adalah "input / output".
Kamerad Che
247

CPU Bound berarti tingkat kemajuan proses dibatasi oleh kecepatan CPU. Tugas yang melakukan perhitungan pada sejumlah kecil angka, misalnya mengalikan matriks kecil, kemungkinan terikat CPU.

I / O Bound berarti laju kemajuan suatu proses dibatasi oleh kecepatan subsistem I / O. Tugas yang memproses data dari disk, misalnya, menghitung jumlah baris dalam file cenderung terikat I / O.

Batas memori berarti laju kemajuan suatu proses dibatasi oleh jumlah memori yang tersedia dan kecepatan akses memori itu. Tugas yang memproses data memori dalam jumlah besar, misalnya mengalikan matriks besar, kemungkinan adalah Memory Bound.

Batas cache berarti tingkat kemajuan proses dibatasi oleh jumlah dan kecepatan cache yang tersedia. Tugas yang hanya memproses lebih banyak data daripada yang cocok dengan cache akan terikat cache.

I / O Bound akan lebih lambat dari Memory Bound akan lebih lambat dari Cache Bound akan lebih lambat dari CPU Bound.

Solusi untuk terikat I / O tidak harus mendapatkan Memori lebih banyak. Dalam beberapa situasi, algoritma akses dapat dirancang di sekitar batasan I / O, Memori atau Cache. Lihat Algoritma Cache Oblivious .

Sanjaya R
sumber
73

Multi-threading

Dalam jawaban ini, saya akan menyelidiki satu kasus penggunaan penting yang membedakan antara pekerjaan yang dibatasi CPU vs IO: saat menulis kode multi-utas.

RAM I / O terikat contoh: Jumlah Sum

Pertimbangkan program yang menjumlahkan semua nilai dari satu vektor:

#define SIZE 1000000000
unsigned int is[SIZE];
unsigned int sum = 0;
size_t i = 0;
for (i = 0; i < SIZE; i++)
    /* Each one of those requires a RAM access! */
    sum += is[i]

Memparalelkannya dengan memisahkan array secara merata untuk masing-masing inti Anda adalah kegunaan terbatas pada desktop modern yang umum.

Sebagai contoh, pada Ubuntu 19.04 saya, laptop Lenovo ThinkPad P51 dengan CPU: CPU Intel Core i7-7820HQ (4 core / 8 thread), RAM: 2x Samsung M471A2K43BB1-CRC (2x 16GiB) Saya mendapatkan hasil seperti ini:

masukkan deskripsi gambar di sini

Plot data .

Perhatikan bahwa ada banyak perbedaan antara proses. Tapi saya tidak bisa meningkatkan ukuran array lebih jauh karena saya sudah di 8GiB, dan saya tidak berminat untuk statistik di beberapa berjalan hari ini. Namun ini seperti menjalankan biasa setelah melakukan banyak menjalankan manual.

Kode benchmark:

Saya tidak tahu arsitektur komputer yang cukup untuk sepenuhnya menjelaskan bentuk kurva, tetapi satu hal yang jelas: perhitungan tidak menjadi 8x lebih cepat seperti yang diharapkan secara naif karena saya menggunakan semua 8 thread saya! Untuk beberapa alasan, 2 dan 3 utas adalah yang optimal, dan menambahkan lebih banyak hanya membuat segalanya lebih lambat.

Bandingkan ini dengan pekerjaan yang terikat CPU, yang sebenarnya mendapatkan 8 kali lebih cepat: Apa arti 'nyata', 'pengguna' dan 'sistem' dalam output waktu (1)?

Alasannya adalah semua prosesor berbagi bus memori tunggal yang terhubung ke RAM:

CPU 1   --\    Bus    +-----+
CPU 2   ---\__________| RAM |
...     ---/          +-----+
CPU N   --/

jadi bus memori dengan cepat menjadi hambatan, bukan CPU.

Ini terjadi karena menambahkan dua angka membutuhkan satu siklus CPU, memori membaca membutuhkan sekitar 100 siklus CPU pada perangkat keras 2016.

Jadi pekerjaan CPU yang dilakukan per byte input data terlalu kecil, dan kami menyebutnya proses yang terikat IO.

Satu-satunya cara untuk mempercepat perhitungan itu lebih jauh, adalah mempercepat akses memori individu dengan perangkat keras memori baru, misalnya memori multi-channel .

Meng-upgrade ke jam CPU yang lebih cepat misalnya tidak akan sangat berguna.

Contoh lainnya

Cara mengetahui apakah Anda terikat CPU atau IO

IO Non-RAM terikat seperti disk, jaringan ps aux:, lalu periksa apakah CPU% / 100 < n threads. Jika ya, Anda terikat IO, misalnya pemblokiran readhanya menunggu data dan penjadwal melewatkan proses itu. Kemudian gunakan alat lebih lanjut sudo iotopuntuk memutuskan IO mana yang merupakan masalah sebenarnya.

Atau, jika eksekusi cepat, dan Anda menentukan jumlah utas, Anda dapat melihatnya dengan mudah dari timekinerja yang meningkat ketika jumlah utas meningkat untuk pekerjaan yang terikat CPU: Apa arti 'nyata', 'pengguna' dan 'sistem' di output waktu (1)?

Ikatan RAM-IO: sulit diketahui, karena waktu tunggu RAM termasuk dalam CPU%pengukuran, lihat juga:

Beberapa opsi:

GPU

GPU memiliki hambatan IO ketika Anda pertama kali mentransfer data input dari RAM yang dapat dibaca CPU biasa ke GPU.

Oleh karena itu, GPU hanya bisa lebih baik daripada CPU untuk aplikasi yang terikat CPU.

Namun begitu data ditransfer ke GPU, ia dapat beroperasi pada byte itu lebih cepat daripada CPU, karena GPU:

  • memiliki lebih banyak pelokalan data daripada kebanyakan sistem CPU, sehingga data dapat diakses lebih cepat untuk beberapa core daripada yang lain

  • mengeksploitasi paralelisme data dan mengorbankan latensi dengan hanya melompati data apa pun yang tidak siap untuk segera dioperasikan.

    Karena GPU harus beroperasi pada data input paralel besar, lebih baik lewati saja ke data berikutnya yang mungkin tersedia alih-alih menunggu data saat ini tersedia dan memblokir semua operasi lain seperti kebanyakan CPU lakukan.

Karena itu GPU dapat lebih cepat daripada CPU jika aplikasi Anda:

  • dapat sangat diparalelkan: potongan data yang berbeda dapat diperlakukan secara terpisah satu sama lain pada saat yang sama
  • membutuhkan jumlah operasi per byte input yang cukup besar (tidak seperti mis. penambahan vektor yang hanya melakukan satu penambahan per byte)
  • ada sejumlah besar byte input

Pilihan desain ini awalnya menargetkan aplikasi rendering 3D, yang langkah utamanya adalah seperti yang ditunjukkan pada Apa itu shader di OpenGL dan untuk apa kita membutuhkannya?

  • vertex shader: mengalikan sekelompok vektor 1x4 dengan matriks 4x4
  • fragment shader: menghitung warna setiap piksel segitiga berdasarkan posisi relatifnya dengan segitiga

jadi kami menyimpulkan bahwa aplikasi itu terikat CPU.

Dengan munculnya GPGPU yang dapat diprogram, kita dapat mengamati beberapa aplikasi GPGPU yang berfungsi sebagai contoh operasi terikat CPU:

Lihat juga:

CPython Global Intepreter Lock (GIL)

Sebagai studi kasus cepat, saya ingin menunjukkan Python Global Interpreter Lock (GIL): Apa itu kunci juru bahasa global (GIL) di CPython?

Detail implementasi CPython ini mencegah banyak utas Python efisien menggunakan pekerjaan yang terikat CPU. Dokumen CPython mengatakan:

Detail implementasi CPython: Di CPython, karena Global Interpreter Lock, hanya satu utas yang dapat mengeksekusi kode Python sekaligus (walaupun pustaka yang berorientasi kinerja tertentu mungkin mengatasi batasan ini). Jika Anda ingin aplikasi Anda memanfaatkan sumber daya komputasi mesin multi-core dengan lebih baik, Anda disarankan untuk menggunakan multiprocessingatau concurrent.futures.ProcessPoolExecutor. Namun, threading masih merupakan model yang tepat jika Anda ingin menjalankan beberapa tugas yang terikat I / O secara bersamaan.

Oleh karena itu, di sini kita memiliki contoh di mana konten yang terikat CPU tidak cocok dan I / O terikat.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber
1
Man, bagaimana Anda bisa menjadi sangat kompeten dan menulis seperti ini?
Mikayil Abdullayev
1
@MikayilAbdullayev terima kasih! Saya cenderung hanya menjawab "pertanyaan penting" dan saya cenderung untuk kembali ke mereka berulang kali ketika saya belajar hal-hal baru yang relevan.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
31

Ikatan CPU berarti program macet oleh CPU, atau unit pemrosesan pusat, sedangkan I / O terikat berarti program macet oleh I / O, atau input / output, seperti membaca atau menulis ke disk, jaringan, dll.

Secara umum, ketika mengoptimalkan program komputer, seseorang mencoba mencari hambatan dan menghilangkannya. Mengetahui bahwa program Anda terikat CPU membantu, sehingga orang tidak perlu mengoptimalkan hal lain.

[Dan dengan "bottleneck", maksud saya hal yang membuat program Anda menjadi lebih lambat daripada yang seharusnya.]

Chris W. Rea
sumber
22

Cara lain untuk mengungkapkan ide yang sama:

  • Jika mempercepat CPU tidak mempercepat program Anda, itu mungkin I / O terikat.

  • Jika mempercepat I / O (mis. Menggunakan disk yang lebih cepat) tidak membantu, program Anda mungkin terikat CPU.

(Saya menggunakan "mungkin" karena Anda perlu mempertimbangkan sumber daya lain. Memori adalah salah satu contohnya.)

Gimel
sumber
11

Ketika program Anda menunggu I / O (mis. Disk baca / tulis atau baca / tulis jaringan dll), CPU bebas untuk melakukan tugas-tugas lain bahkan jika program Anda dihentikan. Kecepatan program Anda sebagian besar akan bergantung pada seberapa cepat IO dapat terjadi, dan jika Anda ingin mempercepatnya, Anda harus mempercepat I / O.

Jika program Anda menjalankan banyak instruksi program dan tidak menunggu I / O, maka dikatakan terikat dengan CPU. Mempercepat CPU akan membuat program berjalan lebih cepat.

Dalam kedua kasus, kunci untuk mempercepat program mungkin bukan untuk mempercepat perangkat keras, tetapi untuk mengoptimalkan program untuk mengurangi jumlah IO atau CPU yang dibutuhkan, atau untuk membuatnya melakukan I / O sementara itu juga melakukan intensif CPU barang.

Paul Tomblin
sumber
6

I / O terikat mengacu pada suatu kondisi di mana waktu yang diperlukan untuk menyelesaikan perhitungan ditentukan terutama oleh periode yang dihabiskan menunggu operasi input / output yang akan diselesaikan.

Ini adalah kebalikan dari tugas yang terikat CPU. Keadaan ini muncul ketika tingkat di mana data diminta lebih lambat daripada tingkat itu dikonsumsi atau, dengan kata lain, lebih banyak waktu dihabiskan meminta data daripada memprosesnya.

FellyTone84
sumber
6

IO terikat proses: menghabiskan lebih banyak waktu melakukan IO daripada perhitungan, memiliki banyak ledakan CPU pendek. Proses terikat CPU: menghabiskan lebih banyak waktu melakukan perhitungan, beberapa ledakan CPU yang sangat panjang

doa
sumber
2

Lihat apa yang dikatakan Microsoft.

Inti dari pemrograman async adalah objek Tugas dan Tugas, yang memodelkan operasi asinkron. Mereka didukung oleh async dan menunggu kata kunci. Model ini cukup sederhana dalam banyak kasus:

  • Untuk kode I / O-terikat, Anda menunggu operasi yang mengembalikan Tugas atau Tugas di dalam metode async.

  • Untuk kode yang terikat CPU, Anda menunggu operasi yang dimulai pada utas latar belakang dengan metode Task.Run.

Kata kunci yang menunggu adalah tempat keajaiban terjadi. Ini menghasilkan kontrol untuk penelepon metode yang dilakukan menunggu, dan pada akhirnya memungkinkan UI menjadi responsif atau layanan menjadi elastis.

Contoh I / O-Bound: Mengunduh data dari layanan web

private readonly HttpClient _httpClient = new HttpClient();

downloadButton.Clicked += async (o, e) =>
{
    // This line will yield control to the UI as the request
    // from the web service is happening.
    //
    // The UI thread is now free to perform other work.
    var stringData = await _httpClient.GetStringAsync(URL);
    DoSomethingWithData(stringData);
};

Contoh terikat CPU: Melakukan Perhitungan untuk Game

private DamageResult CalculateDamageDone()
{
    // Code omitted:
    //
    // Does an expensive calculation and returns
    // the result of that calculation.
}

calculateButton.Clicked += async (o, e) =>
{
    // This line will yield control to the UI while CalculateDamageDone()
    // performs its work.  The UI thread is free to perform other work.
    var damageResult = await Task.Run(() => CalculateDamageDone());
    DisplayDamage(damageResult);
};

Contoh di atas menunjukkan bagaimana Anda dapat menggunakan async dan menunggu untuk pekerjaan I / O-terikat dan CPU-terikat. Ini kuncinya yang dapat Anda identifikasi ketika pekerjaan yang perlu Anda lakukan adalah I / O-terikat atau CPU-terikat, karena itu dapat sangat mempengaruhi kinerja kode Anda dan berpotensi menyebabkan penyalahgunaan konstruksi tertentu.

Berikut adalah dua pertanyaan yang harus Anda tanyakan sebelum Anda menulis kode:

Apakah kode Anda akan "menunggu" untuk sesuatu, seperti data dari database?

  • Jika jawaban Anda adalah "ya", maka pekerjaan Anda terikat I / O.

Apakah kode Anda akan melakukan perhitungan yang sangat mahal?

  • Jika Anda menjawab "ya", maka pekerjaan Anda terikat CPU.

Jika pekerjaan yang Anda miliki terikat I / O, gunakan async dan tunggu tanpa Task.Run . Anda tidak harus menggunakan Perpustakaan Paralel Tugas. Alasan untuk ini diuraikan dalam artikel Async in Depth .

Jika pekerjaan yang Anda miliki terikat dengan CPU dan Anda peduli tentang responsif, gunakan async dan tunggu tetapi menelurkan pekerjaan di utas lain dengan Task.Run. Jika pekerjaan sesuai untuk konkurensi dan paralelisme, Anda juga harus mempertimbangkan menggunakan Perpustakaan Tugas Paralel .

Taşyürek Gökşah
sumber
2

Aplikasi terikat dengan CPU ketika kinerja aritmatika / logis / floating-point (A / L / FP) selama eksekusi sebagian besar mendekati kinerja puncak teoritis prosesor (data yang disediakan oleh pabrikan dan ditentukan oleh karakteristik prosesor). prosesor: jumlah inti, frekuensi, register, ALU, FPU, dll.).

Kinerja mengintip sangat sulit dicapai dalam aplikasi dunia nyata, karena tidak mungkin dikatakan mustahil. Sebagian besar aplikasi mengakses memori di berbagai bagian eksekusi dan prosesor tidak melakukan operasi A / L / FP selama beberapa siklus. Ini disebut Keterbatasan Von Neumann karena jarak yang ada antara memori dan prosesor.

Jika Anda ingin berada di dekat kinerja puncak CPU, strategi dapat mencoba untuk menggunakan kembali sebagian besar data dalam memori cache untuk menghindari memerlukan data dari memori utama. Algoritma yang mengeksploitasi fitur ini adalah perkalian matriks-matriks (jika kedua matriks dapat disimpan dalam memori cache). Ini terjadi karena jika ukuran matrik n x nmaka yang perlu Anda lakukan tentang 2 n^3operasi hanya menggunakan 2 n^2nomor data FP. Di sisi lain penambahan matriks, misalnya, adalah aplikasi yang lebih sedikit terikat CPU atau lebih banyak memori daripada multiplikasi matriks karena hanya membutuhkan n^2FLOP dengan data yang sama.

Pada gambar berikut, FLOP yang diperoleh dengan algoritma naif untuk penambahan matriks dan perkalian matriks dalam Intel i5-9300H, ditunjukkan:

FLOP membandingkan antara Penambahan Matriks dan Penggandaan Matriks

Perhatikan bahwa seperti yang diharapkan kinerja perkalian matriks lebih besar dari penambahan matriks. Hasil ini dapat direproduksi dengan menjalankan test/gemmdan test/mataddtersedia di repositori ini .

Saya sarankan juga untuk melihat video yang diberikan oleh J. Dongarra tentang efek ini.

GG1991
sumber
1

Proses I / O Bound: - Jika sebagian besar masa hidup suatu proses dihabiskan dalam kondisi i / o, maka prosesnya adalah proses terikat a / o. Contoh: -kalkulator, penjelajah internet

Proses Terikat CPU: - Jika sebagian besar umur proses dihabiskan dalam cpu, maka itu adalah proses cpu terikat.

K.Abhishek
sumber
8
Bagaimana kalkulator menjadi proses IO terikat? Tentunya itu akan terikat CPU. Jika kalkulator Anda menghabiskan sebagian besar waktunya diblokir dengan mengakses jaringan atau disk, maka saya sarankan ada yang salah dengan itu.
rickerbh
6
Saya pikir contoh kalkulatornya jelas: sebagian besar waktu menunggu pengguna untuk menekan tombol, sehingga menunggu I / O.
psp
1
@psp benar tetapi contoh kalkulator masih sangat sulit dilihat sebagai terikat karena namanya, "kalkulator." Itu menyiratkan bahwa tujuan utama program adalah untuk melakukan perhitungan cpu yang panjang, tetapi jika Anda melihat kalkulator di desktop Anda itu adalah yang sangat sederhana yang hanya melakukan perhitungan yang membutuhkan nanodetik untuk menyelesaikannya. Jadi sebagian besar waktu menunggu input pengguna, yaitu IO.
Calicoder