Rabu, 17 Desember 2008

SUPERSCALAR VS SUPERPIPELINED

Ø Superscalar

superscalar CPU arsitektur menerapkan suatu bentuk paralel disebut-tingkat instruksi paralel dalam satu prosesor. Ia sehingga memungkinkan lebih cepat CPU akan dibandingkan Throughput lain mungkin pada jam yang sama menilai. Sebuah prosesor superscalar melaksanakan lebih dari satu instruksi selama satu jam secara bersamaan dengan siklus dispatching beberapa petunjuk ke membazir fungsional unit pada prosesor. Setiap unit fungsional tidak terpisah CPU inti, tetapi sebuah sumber daya eksekusi dalam satu CPU seperti aritmetika logis unit, sedikit Shifter, atau kelipatan.

Sementara superscalar CPU biasanya juga pipelined, mereka adalah dua teknik peningkatan kinerja yang berbeda. Hal ini secara teoritis memungkinkan untuk mendapatkan non-pipelined superscalar CPU atau pipelined non-superscalar CPU.

Teknik superscalar yang secara tradisional terkait dengan mengidentifikasi beberapa karakteristik. Catatan ini diterapkan dalam suatu CPU inti.

• Instruksi yang dikeluarkan dari berurutan instruksi streaming

• CPU hardware secara dinamis untuk memeriksa dependensi data antara petunjuk berjalan di waktu (versus perangkat lunak memeriksa di waktu kompilasi)

• Terima petunjuk beberapa jam per siklus

B

Sederhana superscalar pipa. Dengan mengambil dua dispatching dan petunjuk sekaligus, maksimal dua instruksi per siklus dapat diselesaikan.

C

Processor papan yang CRAY T3e supercomputer dengan empat prosesor superscalar Alpha 21164

Sejarah

Seymour Cray's CDC 6600 dari 1965 sering disebut sebagai pertama superscalar desain. Intel i960CA (1988) dan seri AMD 29000-29050 (1990) mikro yang komersial pertama chip tunggal superscalar mikro. CPU RISC seperti ini membawa konsep superscalar untuk mikro komputer RISC karena hasil desain yang sederhana inti, agar mudah instruksi dispatch dan keterlibatan beberapa unit fungsional (seperti ALUs) pada satu CPU dalam rancangan peraturan yang terpaksa waktu. Ini adalah alasan yang RISC desain yang lebih cepat dari CISC desain melalui ke dalam tahun 1980-an dan 1990-an.

Kecuali untuk digunakan dalam beberapa CPU-daya baterai perangkat, pada dasarnya semua tujuan-CPU umum dikembangkan sejak 1998 adalah superscalar. Diawali dengan "P6" (Pentium Pro dan Pentium II) pelaksanaan, Intel x86 arsitektur mikro yang telah menerapkan CISC pada set instruksi RISC superscalar mikro. Kompleks petunjuk yang diterjemahkan secara internal ke-RISC seperti "micro-ops" set instruksi RISC, prosesor yang memungkinkan untuk mengambil keuntungan dari performa yang lebih tinggi-prosesor yang melandasi tetap kompatibel dengan prosesor Intel sebelumnya.

Dari skalar untuk superscalar

Prosesor yang paling sederhana adalah skalar prosesor. Setiap instruksi dijalankan oleh prosesor skalar manipulates biasanya satu atau dua item data sekaligus. Sebaliknya, setiap instruksi yang dijalankan oleh prosesor vector beroperasi secara simultan pada banyak data item. Sebuah analogi adalah perbedaan antara skalar dan vector aritmatika. Sebuah prosesor superscalar adalah jenis campuran ke dua. Setiap instruksi proses data satu item, namun ada beberapa fungsional berlebihan dalam setiap unit CPU sehingga beberapa petunjuk dapat memproses data terpisah item serentak.

Superscalar desain CPU menekankan peningkatan instruksi memberangkatkan akurasi, dan mengoperasikannya menyimpan beberapa unit fungsional digunakan setiap waktu. Hal ini menjadi semakin penting ketika jumlah unit meningkat. Sementara awal superscalar CPU akan memiliki dua ALUs dan satu fpu, desain yang modern seperti PowerPC 970 mencakup empat ALUs, dua FPUs, dan dua unit SIMD. Jika memberangkatkan adalah menjaga tidak efektif di semua unit bosan dengan petunjuk, kinerja sistem akan menderita.

A superscalar prosesor biasanya sustains yang menilai pelaksanaan melebihi satu instruksi per siklus mesin. Tetapi hanya memproses beberapa instruksi serentak tidak membuat sebuah arsitektur superscalar, sejak pipelined, multiprocessor atau multi-inti yang mencapai arsitektur juga, tetapi dengan metode yang berbeda.

Dalam superscalar CPU yang memberangkatkan bacaan instruksi dari memori dan memutuskan mana yang dapat dijalankan secara paralel, dispatching mereka ke membazir unit fungsional yang terdapat di dalam satu CPU. Oleh karena itu prosesor superscalar dapat envisioned memiliki beberapa pipa paralel, yang masing-masing adalah instruksi pemrosesan secara simultan dari sebuah instruksi benang.

Keterbatasan

Tersedia dari peningkatan kinerja superscalar teknik dibatasi oleh dua bidang utama:

• Tingkat dari hakiki paralel dalam instruksi streaming, yakni terbatasnya jumlah instruksi level parallelism, dan

• Kompleksitas waktu dan biaya yang terkait memberangkatkan dan ketergantungan memeriksa logika.

Binari yang ada telah dijalankan program tahap hakiki paralel. Dalam beberapa kasus petunjuk tidak tergantung pada satu sama lain dan dapat dijalankan secara bersamaan. Dalam kasus lain mereka yang antar-tergantung: satu instruksi dampak baik sumber daya atau hasil lainnya. Petunjuk yang = b + c; d = e + f dapat berjalan secara bersamaan karena tidak ada yang bergantung pada hasil perhitungan lain. Namun, petunjuk yang = b + c; d = a + f mungkin tidak akan runnable secara paralel, tergantung pada urutan petunjuk yang lengkap saat mereka bergerak melalui unit.

Bila jumlah yang dikeluarkan secara simultan petunjuk meningkat, biaya memeriksa dependensi meningkat sangat pesat. Hal ini diperparah oleh kebutuhan untuk memeriksa dependensi di waktu dan menjalankan di CPU jam menilai. Ini termasuk biaya tambahan gerbang logika diperlukan untuk melaksanakan pemeriksaan, dan waktu tunda yang melalui pintu. Penelitian menunjukkan pintu gerbang biaya dalam beberapa kasus dapat NK pintu, dan biaya keterlambatan k2logn, dimana n adalah jumlah instruksi pada prosesor's set instruksi, dan k adalah jumlah bersamaan menurunkan petunjuk. Dalam matematika, ini disebut sebagai combinatoric masalah melibatkan permutations.

Meski mungkin berisi instruksi streaming tidak antar-instruksi dependensi, superscalar CPU yang sebenarnya harus memeriksa bahwa kemungkinan, karena tidak ada jaminan lain dan kegagalan untuk mendeteksi suatu dependensi akan menghasilkan hasil yang salah.

Tidak peduli bagaimana lanjutan proses yang semikonduktor atau cara cepat kecepatan yang berpindah, ini tempat yang praktis membatasi berapa petunjuk dapat menurunkan secara bersamaan. Meskipun proses kemajuan akan mengijinkan pernah lebih besar jumlah unit fungsional (misalnya, ALUs), beban instruksi memeriksa dependensi sehingga tumbuh pesat yang dicapai superscalar dispatch batas relatif kecil. - Kemungkinan pada urutan lima hingga enam secara bersamaan menurunkan petunjuk.

Namun akhirnya tak terhingga cepat memeriksa ketergantungan pada logika konvensional yang lain superscalar CPU, jika instruksi streaming itu sendiri memiliki banyak dependensi, ini juga akan membatasi speedup mungkin. Dengan demikian tingkat hakiki paralel dalam kode streaming bentuk kedua keterbatasan.

Alternatif

Secara kolektif, kedua batas berkendara investigasi ke alternatif arsitektur meningkatkan kinerja seperti Long Sangat Instruksi Word (VLIW), secara paralel Instruksi Computing (EPIC), serentak multithreading (SMT), dan multi-core.

Dengan VLIW, tugas yang memberatkan ketergantungan memeriksa hardware dengan logika berjalan di waktu akan dihapus dan didelegasikan kepada compiler. Instruksi secara paralel Computing (EPIC) adalah seperti VLIW, dengan tambahan cache prefetching petunjuk.

Serentak multithreading, sering disingkat sebagai SMT, adalah teknik untuk meningkatkan efisiensi superscalar CPU. SMT izin dari beberapa rangkaian independen untuk pelaksanaan lebih baik memanfaatkan sumber daya yang disediakan oleh prosesor arsitektur modern.

Superscalar berbeda dari prosesor multi-core yang berlebihan di unit fungsional tidak seluruh prosesor. Satu prosesor terdiri dari halus-halus unit fungsional seperti ALU, kelipatan bulat, bulat Shifter, floating point unit, dll Mungkin ada beberapa versi dari masing-masing unit fungsional untuk memungkinkan pelaksanaan banyak instruksi secara paralel. Ini berbeda dari multicore CPU yang serentak proses instruksi dari beberapa rangkaian, satu per benang inti. Ia juga berbeda dari pipelined CPU, dimana beberapa instruksi dapat dilakukan serentak di berbagai tahapan pelaksanaan, assembly-line mode.

Berbagai alternatif teknik tidak saling eksklusif-mereka dapat (dan sering adalah) digabungkan dalam satu prosesor. Dengan demikian yang multicore CPU dapat di mana masing-masing inti adalah independen prosesor berisi beberapa pipa paralel, masing-masing pipa yang superscalar. Beberapa prosesor juga termasuk vector kemampuan

Ø Superpipeline

Sebuah instruksi pipa merupakan teknik yang digunakan dalam desain komputer dan perangkat elektronik digital lain untuk meningkatkan instruksi Throughput (jumlah instruksi yang dapat dijalankan di sebuah unit waktu).

Ide yang mendasar adalah untuk membagi pemrosesan instruksi dari komputer ke serangkaian langkah-langkah independen, dengan penyimpanan pada akhir setiap langkah. Hal ini memungkinkan komputer kontrol circuitry untuk mengeluarkan instruksi pada pengolahan menilai langkah yang lambat, yang jauh lebih cepat daripada waktu yang dibutuhkan untuk melakukan semua langkah sekaligus. Istilah pipa merujuk kepada fakta bahwa setiap langkah yang membawa data sekaligus (seperti air), dan setiap langkah terhubung ke depan (seperti link dari sebuah pipa.)

400px-Fivestagespipeline

Dasar-tahap lima pipa di mesin RISC (JIKA = Instruksi Fetch, ID = Instruksi sandi, EX = Jalankan, Mem = memori akses, WB = Daftar menulis kembali). Sumbu vertikal adalah petunjuk berturut-turut, sumbu horisontal adalah waktu. Jadi dalam kolom hijau, paling awal adalah instruksi dalam tahap WB, dan yang terbaru adalah melakukan instruksi mengambil instruksi.

Asal pipelining ini dianggap menjadi baik ILLIAC II proyek atau IBM Tegangkan proyek. IBM Project Tegangkan mengusulkan istilah, "Fetch, sandi, dan Jalankan" yang menjadi penggunaan umum.

Kebanyakan CPU modern digerakkan oleh jam. CPU terdiri dari logika internal dan memori (balikkan flops). Ketika jam sinyal datang, yang membalik flops baru mereka mengambil nilai dan logika kemudian memerlukan waktu untuk membaca sandi baru nilai. Kemudian berikutnya jam tiba berdebar-debar dan penerjunan flops lagi mereka mengambil nilai-nilai baru, dan sebagainya. Dengan menggunakan sarana dan logika menjadi potongan-potongan kecil dan memasukkan penerjunan flops antara potongan-potongan logika, penundaan sebelum berlaku logika memberikan output berkurang. Dengan cara ini jam periode dapat dikurangi. Misalnya, RISC pipa yang rusak ke dalam lima tahap dengan satu set penerjunan flops antara masing-masing tahap.

1. Instruksi mengambil

2. Instruksi sandi mendaftar dan mengambil

3. Jalankan

4. Memori akses

5. Daftar menulis kembali

Bahaya: Ketika programmer (atau compiler) menulis kode assembly, mereka membuat asumsi bahwa setiap instruksi akan dijalankan sebelum eksekusi dari perintah itu mulai berlaku. Ini adalah asumsi batal dengan pipelining. Bila ini menyebabkan program untuk bertingkah salah, situasi yang dikenal sebagai bahaya. Berbagai teknik untuk menyelesaikan bahaya seperti forwarding dan stalling ada.

A non-pipa arsitektur adalah tidak efisien karena beberapa komponen CPU (modul) yang menganggur sementara modul lain adalah aktif selama siklus instruksi. Pipelining tidak sepenuhnya batal waktu idle dalam CPU tetapi membuat modul yang bekerja secara paralel meningkatkan pelaksanaan program secara signifikan.

Prosesor dengan pipelining diselenggarakan dalam ke tahap yang dapat bekerja secara mandiri semi-terpisah pada pekerjaan. Setiap tahap ini disusun dan dihubungkan ke dalam 'rantai' sehingga setiap tahap output adalah ke didulang lain sampai tahap pekerjaan dilakukan. Organisasi ini memungkinkan prosesor dari keseluruhan proses timne akan berkurang secara signifikan.

Sayangnya, tidak semua instruksi yang independen. Dalam sederhana, saluran menyelesaikan instruksi yang mungkin memerlukan tahap 5. Beroperasi pada kinerja penuh, pipa ini akan perlu menjalankan 4 instruksi independen berlaku saat pertama adalah menyelesaikan. Jika 4 petunjuk yang tidak tergantung pada output dari perintah pertama tidak ada, pipa kontrol logika harus memasukkan warung atau disia-siakan jam ke dalam siklus milsadenSi sampai ketergantungan diselesaikan. Untungnya, teknik seperti forwarding dapat secara signifikan mengurangi kasus dimana stalling diperlukan. Walaupun secara teori pipelining dapat meningkatkan kinerja selama unpipelined inti oleh faktor jumlah tahap (asumsi jam skala frekuensi juga dengan jumlah tahapan), pada kenyataannya, kebanyakan kode tidak mengijinkan ideal untuk eksekusi.

Kelebihan dan Kekurangan

Pipelining tidak membantu dalam semua kasus. Ada beberapa kekurangan. Sebuah instruksi pipa dikatakan sepenuhnya pipelined jika dapat menerima instruksi baru setiap siklus jam. Sebuah pipa yang tidak sepenuhnya pipelined siklus yang telah menunggu keterlambatan kemajuan dari pipa.

Kelebihan Pipelining:

Lingkaran waktu dari prosesor berkurang, sehingga meningkatkan tingkat instruksi-isu dalam banyak kasus.

Beberapa kombinasi sirkuit seperti adders atau multipliers dapat dibuat lebih cepat dengan menambahkan lebih circuitry. Jika pipelining digunakan sebagai gantinya, ia dapat menyimpan circuitry vs kombinasi yang lebih kompleks sirkuit.

Kekurangan Pipelining:

A non-pipelined prosesor mengeksekusinya hanya satu instruksi pada satu waktu. Ini mencegah penundaan cabang (yang berlaku, setiap cabang tertunda) dan masalah dengan serial instruksi yang dilaksanakan serentak. Akibatnya desain yang lebih sederhana dan lebih murah untuk pembuatan.

Instruksi yang latensi di non-pipelined prosesor sedikit lebih rendah dari dalam pipelined setara. Hal ini disebabkan oleh fakta bahwa tambahan penerjunan flops harus ditambahkan ke data path dari pipelined prosesor.

A non-pipelined prosesor akan memiliki instruksi bandwidth stabil. Kinerja pipelined prosesor yang jauh dan sulit untuk memprediksi secara lebih luas dapat bervariasi antara program yang berbeda.

Contoh

Generik Pipeline

Ke kanan adalah generik pipa dengan empat tahap:

1. Mengambil

2. Sandi

3. Jalankan

4. Write-back

Bagian atas kotak abu-abu adalah petunjuk dari daftar tunggu untuk dieksekusi; bagian bawah kotak abu-abu adalah daftar instruksi yang telah selesai dan tengah kotak putih adalah pipa.

A

Generik 4-tahap pipa; kotak berwarna yang mewakili petunjuk independen satu sama lainnya

Pelaksanaan adalah sebagai berikut:

Waktu

pelaksanaan

0

· Empat menunggu instruksi yang akan dilaksanakan

1

· hijau instruksi yang diambil dari memori

2

· instruksi yang ungu ini diambil dari memori

3

· hijau instruksi akan dijalankan (sebenarnya dilakukan operasi)

· instruksi yang ungu adalah decoded

· biru adalah instruksi diambil

4

· hijau instruksi hasil's ditulis kembali ke file atau mendaftar memori

· ungu instruksi yang akan dijalankan

· biru adalah instruksi decoded

· merah adalah instruksi diambil

5

· hijau instruksi selesai

· ungu instruksi yang ditulis kembali

· biru instruksi akan dijalankan

· merah adalah instruksi decoded

6

· instruksi yang ungu selesai

· biru instruksi yang ditulis kembali

· merah instruksi akan dijalankan

7

· biru instruksi selesai

· merah adalah instruksi yang ditulis kembali

8

· merah instruksi selesai

9

· Semua instruksi dijalankan

Bubble

Ketika "tersendat" di eksekusi terjadi, sebuah "gelembung" dibuat di dalam pipa yang tidak berguna terjadi. Pada siklus 2, mengambil dari ungu perintah itu tertunda dan decoding tahap dalam siklus 3 sekarang berisi gelembung. Semuanya "di belakang" ungu instruksi yang tertunda juga tetapi semuanya "maju" dari ungu instruksi melanjutkannya dengan pelaksanaan.

Jelas, bila dibandingkan dengan pelaksanaan di atas, gelembung hasil total waktu pelaksanaan 8 jam ticks bukan 7.

Gelembung adalah seperti kedai, di mana tidak akan terjadi berguna untuk mengambil, sandi, dan jalankan writeback. Hal ini dapat diselesaikan dengan PDN kode.

375px-Pipeline_4_stage_with_bubble

Sebuah gelembung dalam siklus 3 penundaan eksekusi

Contoh 1

Sebuah khas instruksi untuk menambahkan nomor dua mungkin ADD A, B, C, menambahkan nilai-nilai yang ditemukan di lokasi memori A dan B, dan kemudian meletakkan hasil di lokasi memori C. Dalam pipelined prosesor pipa kontrol akan merusak ini menjadi serangkaian tugas serupa untuk:

Beban A, r1

Beban B, r2

ADD r1, R2, R3

Toko R3, C

LOAD berikutnya instruksi

Lokasi 'r1' dan 'R2' adalah register dalam CPU. Nilai-nilai yang disimpan di lokasi memori berlabel 'A' dan 'B' yang dimuat (disalin) ke register ini, kemudian ditambahkan, dan hasilnya akan disimpan di lokasi memori berlabel 'C'.

Dalam contoh ini adalah pipa panjang tiga tahapan-load, jalankan, dan menyimpan. Setiap langkah-langkah yang disebut pipa bertahap.

Pada non-pipelined prosesor, hanya satu tahap dapat bekerja sekaligus sehingga seluruh instruksi harus selesai sebelum instruksi berikutnya dapat mulai. Pada prosesor pipelined, semua tahapan dapat bekerja sekaligus pada berbagai petunjuk. Jadi, saat ini adalah instruksi yang dijalankan di tahap kedua akan instruksi pada tahap sandi dan instruksi akan 3rd di mengambil tahap.

Pipelining tidak mengurangi waktu yang diperlukan untuk menyelesaikan suatu instruksi agak untuk meningkatkan jumlah instruksi yang dapat diproses dan sekaligus mengurangi menyelesaikan keterlambatan antara petunjuk-disebut 'Throughput'. Semakin banyak pipa tahapan yang telah prosesor, semakin banyak instruksi dapat bekerja pada sekaligus dan kurang dari yang ada penundaan antara selesai petunjuk. Setiap hari ini menggunakan mikroprosesor diproduksi sekurang-kurangnya 2 tahap pipa. [Sunting] (The Atmel AVR dan PIC mikrokontroler masing-masing memiliki 2 tahap pipa). Prosesor Intel Pentium 4 memiliki 20 tahap pipa.

Contoh 2

Untuk memvisualisasikan konsep yang lebih baik, kami dapat melihat pada teori-3 tahap pipa:

Tahap

Keterangan

Load

Read instruction from memory

Execute

Execute instruction

Store

Store result in memory and/or registers

dan palsu-kode assembly listing akan dilaksanakan:

LOAD # 40, A; beban di 40 A

Kena A, B; menyalin A di B

ADD # 20, B; untuk menambah 20 B

STORE B, 0x300; menyimpan memori ke dalam sel B 0x300

Ini adalah bagaimana ia akan dilaksanakan:

Clock 1

Load

Execute

Store

LOAD

The LOAD instruction is fetched from memory.

Clock 2

Load

Execute

Store

MOVE

LOAD

The LOAD instruction is executed, while the MOVE instruction is fetched from memory.

Clock 3

Load

Execute

Store

ADD

MOVE

LOAD

LOAD instruksi yang ada di Kedai tahap, di mana para hasil (nomor 40) akan disimpan dalam register A. Dalam Sementara itu, kena instruksi sedang dijalankan. Karena harus memindahkan isi dari A ke B, ia harus menunggu di akhir-akhir dari instruksi LOAD.

Clock 4

Load

Execute

Store

STORE

ADD

MOVE

perintah itu dimuat, sedangkan saya kena perintah itu finishing off dan ADD adalah menghitung.

Dan sebagainya. Perlu diketahui bahwa, kadang-kadang, suatu instruksi akan bergantung pada hasil satu lain (seperti kami kena contoh). Bila lebih dari satu instruksi referensi lokasi tertentu untuk operand, baik itu membaca (sebagai masukan) atau menulis itu (sebagai output), yang melaksanakan instruksi dalam pesanan yang berbeda dari yang asli program pesanan dapat menimbulkan bahaya (yang disebutkan di atas) . Ada beberapa teknik yang didirikan untuk mencegah bahaya baik dari terjadi, atau bekerja di sekitar mereka jika mereka lakukan.

Komplikasi

Banyak desain termasuk pipa sepanjang 7, 10 dan bahkan 20 tahap (seperti di Intel Pentium 4) nanti "Prescott" dan "Cedar Mill" Pentium 4 core (Pentium D dan mereka derivatif) mempunyai tahap-31, saluran yang lama di komputer utama konsumen. Xelerator X10q yang memiliki pipa lebih dari seribu tahapan panjang [1]. Kelemahan dari yang pipa lama adalah ketika sebuah program cabang, seluruh pipa harus bersemangat, masalah yang cabang prediksi untuk membantu meringankan. Cabang prediksi itu sendiri bisa jadi masalah jika keadaan cabang diduga buruk. Dalam aplikasi tertentu, seperti supercomputing, program yang khusus ditulis untuk cabang sehingga sangat jarang dan panjang pipa yang ideal untuk mempercepat yang computations, sebagai panjang pipa yang dirancang untuk mengurangi jam per instruksi (CPI). Jika percabangan terus terjadi, kembali memesan cabang tersebut yang lebih besar untuk menjadi petunjuk yang diperlukan ditempatkan ke dalam pipa secara signifikan dapat mengurangi kerugian yang berhubungan dengan kecepatan harus siram gagal cabang. Program seperti gcov dapat digunakan untuk memeriksa seberapa sering cabang tertentu yang benar-benar dilaksanakan dengan menggunakan teknik yang dikenal sebagai cakupan analisis, namun analisis tersebut adalah yang terakhir sering resor untuk optimasi.

Semakin tinggi Throughput dari pipa jatuh singkat bila dijalankan banyak berisi kode cabang: prosesor tidak dapat mengetahui di mana untuk membaca instruksi berikutnya, dan harus menunggu untuk cabang instruksi untuk menyelesaikan, meninggalkan pipa belakangnya kosong. Setelah cabang sudah terselesaikan, selanjutnya instruksi telah melakukan perjalanan ke semua jalan melalui pipa sebelum menjadi hasil yang tersedia dan prosesor tampaknya "bekerja" lagi. Dalam kasus ekstrim, performa yang pipelined prosesor dapat secara teoritis dari sebuah pendekatan yang un-pipelined prosesor, atau bahkan sedikit lebih buruk jika semua tetapi satu tahapan pipa yang menganggur dan overhead kecil yang hadir antara tahap.

Karena instruksi dari pipa, kode prosesor yang tidak muat akan segera dijalankan. Karena ini, update pada kode sangat dekat dengan lokasi pelaksanaan saat ini mungkin tidak berlaku karena mereka telah dimuat ke dalam prefetch Input Antrian. Instruksi cache fenomena ini membuat lebih buruk lagi. Hal ini hanya relevan untuk memodifikasi program-sendiri.

Tidak ada komentar:

Posting Komentar