Namun C adalah bahasa tingkat rendah


Selama dekade terakhir sejak munculnya bahasa C, banyak bahasa pemrograman yang menarik telah dibuat. Beberapa dari mereka masih digunakan, yang lain telah mempengaruhi generasi bahasa berikutnya, popularitas yang ketiga telah menghilang. Sementara itu, kuno, kontroversial, primitif, dibuat dalam tradisi terburuk dari generasi bahasa C (dan pewarisnya) lebih hidup daripada semua makhluk hidup.


Criticism C adalah genre epistolary klasik untuk industri kami. Kedengarannya lebih keras, lalu lebih tenang, tetapi akhir-akhir ini benar-benar menakjubkan. Contohnya adalah terjemahan dari artikel David Ciswell "C Bukan Bahasa Level Rendah," diterbitkan di blog kami beberapa waktu lalu. Anda dapat mengatakan hal-hal berbeda tentang C, sebenarnya ada banyak kesalahan tidak menyenangkan dalam desain bahasa, tetapi menolak C dalam "level rendah" terlalu banyak!


Agar tidak mentolerir ketidakadilan seperti itu, saya memberanikan diri dan mencoba memutuskan apa bahasa pemrograman tingkat rendah itu dan praktik apa yang mereka inginkan darinya, setelah itu saya membahas argumen para kritikus C. Beginilah artikel ini muncul.


Isi



Argumen Kritik C


Berikut adalah beberapa argumen kritik C, termasuk yang terdaftar dalam sebuah artikel oleh David Chiznell:


  1. Mesin bahasa C abstrak terlalu mirip dengan arsitektur PDP-11 yang sudah ketinggalan zaman, yang telah lama tidak sesuai dengan perangkat prosesor modern yang populer.
  2. Ketidaksesuaian antara mesin abstrak dan perangkat mesin nyata menyulitkan pengembangan pengoptimal bahasa kompiler.
  3. Ketidaklengkapan dan kerumitan standar bahasa menyebabkan perbedaan dalam implementasi standar.
  4. Dominasi bahasa mirip-C tidak memungkinkan mengeksplorasi arsitektur prosesor alternatif.

Pertama-tama mari kita tentukan persyaratan untuk bahasa tingkat rendah, setelah itu kita kembali ke argumen yang diberikan.


Bahasa pemrograman tingkat rendah


Tidak ada definisi bahasa tingkat rendah yang diterima secara universal. Tetapi sebelum membahas masalah kontroversial, diinginkan untuk memiliki setidaknya beberapa persyaratan awal untuk masalah perselisihan.


Tidak ada yang akan berpendapat bahwa bahasa assembly ada di level terendah. Tetapi pada setiap platform itu unik, jadi kode dalam bahasa seperti itu tidak bisa portabel. Bahkan pada platform yang kompatibel ke belakang, Anda mungkin perlu menggunakan beberapa instruksi baru.


Dari sini ikuti persyaratan pertama untuk bahasa tingkat rendah: ia harus mempertahankan fitur umum untuk platform populer . Sederhananya, kompiler harus portabel. Portabilitas kompiler menyederhanakan pengembangan kompiler bahasa untuk platform baru, dan variasi platform yang didukung oleh kompiler menghilangkan kebutuhan pengembang untuk menulis ulang program aplikasi untuk setiap mesin baru.


Persyaratan pertama bertentangan dengan keinginan pengembang program khusus: bahasa pemrograman, driver, sistem operasi dan database berkinerja tinggi. Programmer yang menulis program-program ini ingin dapat mengoptimalkan secara manual, bekerja secara langsung dengan memori, dan sebagainya. Singkatnya, bahasa tingkat rendah harus memungkinkan bekerja dengan detail implementasi platform .


Menemukan keseimbangan antara kedua persyaratan ini - mengidentifikasi aspek-aspek yang umum untuk platform dan mengakses sebanyak mungkin detail - adalah alasan mendasar untuk kesulitan mengembangkan bahasa tingkat rendah.


Perhatikan bahwa abstraksi tingkat tinggi tidak begitu penting untuk bahasa seperti itu - itu lebih penting baginya untuk berfungsi sebagai kontrak antara platform, kompiler dan pengembang. Dan jika ada kontrak, maka ada kebutuhan untuk bahasa yang tidak tergantung pada standar implementasi tertentu .


Persyaratan pertama kami - fitur umum untuk platform target - dinyatakan dalam mesin bahasa abstrak, jadi kami akan memulai diskusi dengan C.


Ini bukan hanya tentang PDP-11


Platform tempat bahasa C muncul adalah PDP-11. Ini didasarkan pada arsitektur von Neumann tradisional, di mana program dijalankan secara berurutan oleh prosesor pusat, dan memori adalah pita datar, di mana data dan program disimpan. Arsitektur seperti itu mudah diimplementasikan dalam perangkat keras, dan seiring waktu, semua komputer tujuan umum mulai menggunakannya.


Perbaikan modern untuk arsitektur von Neumann bertujuan untuk menghilangkan hambatan utamanya - keterlambatan pertukaran data antara prosesor dan memori ( hambatan von Neuman bahasa Inggris). Perbedaan dalam memori dan kinerja CPU menyebabkan munculnya subsistem caching prosesor (level tunggal dan kemudian multi-level).


Tetapi bahkan cache hari ini tidak cukup. Prosesor modern telah menjadi superscalar. Penundaan dalam menerima instruksi dari data memori sebagian dikompensasi oleh eksekusi yang luar biasa ( paralelisme tingkat instruksi ) dari instruksi, ditambah dengan prediktor cabang .


Mesin abstrak berurutan C (dan banyak bahasa lainnya) meniru karya tidak begitu spesifik dari PDP-11, tetapi dari komputer mana pun yang diatur sesuai dengan prinsip arsitektur von Neumann. Ini mencakup arsitektur yang dibangun di sekitar prosesor dengan satu inti: desktop dan server x86, ARM mobile, yang berasal dari tempat Sun / Oracle SPARC dan IBM POWER.


Seiring waktu, beberapa core pemrosesan mulai diintegrasikan ke dalam satu prosesor, sebagai akibatnya menjadi perlu untuk menjaga koherensi cache masing-masing inti dan diperlukan protokol interaksi internuklear. Arsitektur Von Neumann dengan demikian diskalakan ke beberapa core.


Versi asli dari mesin abstrak C adalah berurutan, tidak mencerminkan keberadaan utas eksekusi program yang berinteraksi melalui memori. Munculnya model memori dalam standar memperluas kemampuan mesin abstrak menjadi paralel.


Dengan demikian, pernyataan bahwa mesin C abstrak telah lama tidak konsisten dengan struktur prosesor modern tidak terlalu memperhatikan bahasa tertentu, tetapi komputer yang menggunakan arsitektur von Neumann, termasuk dalam eksekusi paralel.


Tetapi sebagai seorang praktisi, saya ingin mencatat yang berikut: kita dapat mengasumsikan bahwa pendekatan Fonneimann sudah ketinggalan zaman, kita dapat mengasumsikan bahwa itu relevan, tetapi ini tidak membatalkan fakta bahwa arsitektur tujuan umum saat ini menggunakan turunan dari pendekatan tradisional.


Perwujudan standar dan portabel arsitektur von Neumann - mesin C abstrak - mudah diimplementasikan pada semua platform utama dan karenanya menikmati popularitasnya sebagai perakit portabel sepatutnya.


Mengoptimalkan kompiler dan bahasa tingkat rendah


Persyaratan kedua kami untuk bahasa tingkat rendah adalah akses ke detail implementasi tingkat rendah dari masing-masing platform populer. Dalam kasus C, ini adalah pekerjaan langsung dengan memori dan objek di dalamnya sebagai array byte, kemampuan untuk langsung bekerja dengan alamat byte dan aritmatika pointer canggih.


Kritikus C menunjukkan bahwa standar bahasa memberikan terlalu banyak jaminan mengenai, misalnya, lokasi masing-masing bidang dalam struktur dan asosiasi. Bersama dengan pointer dan mekanisme loop primitif ini menyulitkan pekerjaan pengoptimal.


Memang, pendekatan yang lebih deklaratif akan memungkinkan kompiler untuk secara mandiri menyelesaikan masalah penyelarasan data dalam memori atau urutan optimal bidang dalam struktur; dan siklus tingkat yang lebih tinggi memberikan kebebasan yang Anda butuhkan saat membuat vektor.


Posisi pengembang C dalam hal ini adalah sebagai berikut: bahasa tingkat rendah harus memungkinkannya untuk bekerja pada tingkat yang cukup rendah bagi programmer untuk secara mandiri menyelesaikan masalah optimasi. Dalam C, dimungkinkan untuk bekerja sebagai kompiler, memilih, misalnya, instruksi SIMD dan menempatkan data dalam memori dengan benar.


Dengan kata lain, persyaratan kami untuk akses ke detail implementasi dari setiap platform bertentangan dengan keinginan pengembang untuk mengoptimalkan kompiler justru karena kehadiran alat tingkat rendah.


Menariknya, Chiznell dalam sebuah artikel berjudul "C bukan bahasa tingkat rendah" secara paradoks mengklaim bahwa C terlalu rendah, yang menunjukkan tidak adanya alat tingkat tinggi di dalamnya. Tetapi para praktisi benar-benar membutuhkan alat tingkat rendah, jika tidak bahasa tidak dapat digunakan untuk mengembangkan sistem operasi dan program tingkat rendah lainnya, yaitu, itu tidak akan memenuhi persyaratan kedua kami.


Mengalihkan dari uraian masalah optimisasi C, saya ingin mencatat bahwa saat ini tidak ada usaha yang diinvestasikan dalam mengoptimalkan kompiler bahasa tingkat tinggi (C # dan Java yang sama) daripada di GCC atau Dentang. Bahasa fungsional juga memiliki kompiler yang cukup efektif: MLTon, OCaml, dan lainnya. Tetapi para pengembang dari OCaml yang sama masih dapat membanggakan kinerja terbaik di setengah kecepatan kode C ...


Standar sebagai barang mutlak


Dalam artikelnya, Chiznell mengutip hasil survei yang dilakukan pada tahun 2015: banyak programmer membuat kesalahan dalam memecahkan masalah dalam memahami standar C.


Saya kira salah satu pembaca berurusan dengan standar C. Saya memiliki versi kertas C99, 900 halaman iklan. Ini bukan spesifikasi Skema singkat dengan volume kurang dari 100 halaman dan bukan Standar ML menjilat 300. Kesenangan bekerja tidak ada yang mendapatkan standar C: tidak ada pengembang kompiler, atau pengembang dokumen, atau programmer.


Tetapi kita harus memahami bahwa standar C dikembangkan setelah fakta, setelah kemunculan banyak dialek yang kompatibel "hampir tidak ada". Penulis ANSI C telah melakukan pekerjaan yang luar biasa dengan merangkum implementasi yang ada dan meliput dengan banyak “kruk” ketidakteraturan dalam desain bahasa.


Mungkin tampak aneh bahwa seseorang berupaya menerapkan dokumen semacam itu. Tetapi C telah diimplementasikan oleh banyak kompiler. Saya tidak akan menceritakan kembali kisah orang lain tentang kebun binatang dunia UNIX pada akhir 80-an, terutama karena pada saat itu saya sendiri tidak menganggapnya dengan percaya diri dan hanya sampai lima. Tapi, jelas, semua orang di industri benar-benar membutuhkan standar.


Hal yang hebat adalah keberadaannya dan diimplementasikan oleh setidaknya tiga kompiler besar dan banyak kompiler kecil, yang bersama-sama mendukung ratusan platform. Tidak satu pun dari bahasa pesaing C, yang mengklaim mahkota raja dari bahasa tingkat rendah, dapat membanggakan keragaman dan keserbagunaan seperti itu.


Sebenarnya, standar C saat ini tidak terlalu buruk. Seorang programmer yang kurang lebih berpengalaman dapat mengembangkan kompiler C yang tidak mengoptimalkan dalam jumlah waktu yang wajar, yang dikonfirmasi oleh keberadaan banyak implementasi semi-amatir (TCC, LCC dan 8cc yang sama).


Memiliki standar yang diterima secara umum berarti bahwa C memenuhi persyaratan terakhir kami untuk bahasa tingkat rendah: bahasa ini dibangun berdasarkan spesifikasi, bukan implementasi spesifik.


Arsitektur alternatif - komputasi khusus


Tapi Lifewell mengutip argumen lain, kembali ke perangkat prosesor tujuan umum modern yang menerapkan opsi arsitektur von Neumann. Dia mengklaim bahwa masuk akal untuk mengubah prinsip-prinsip prosesor sentral. Sekali lagi, kritik ini tidak khusus untuk C, tetapi untuk model pemrograman imperatif yang paling dasar.


Memang, ada banyak alternatif untuk pendekatan tradisional dengan eksekusi berurutan program: model SIMD dalam gaya GPU, model dalam gaya mesin Erlang abstrak, dan lainnya. Tetapi masing-masing pendekatan ini memiliki penerapan terbatas ketika digunakan dalam prosesor pusat.


GPU, misalnya, berlipat ganda dalam permainan dan pembelajaran mesin, tetapi mereka sulit digunakan untuk ray tracing. Dengan kata lain, model ini cocok untuk akselerator khusus, tetapi tidak berfungsi untuk prosesor tujuan umum.


Erlang bekerja sangat baik dalam sebuah cluster, tetapi sortir cepat yang efisien atau tabel hash yang cepat sulit dilakukan. Model aktor independen lebih baik digunakan pada level yang lebih tinggi, dalam sebuah cluster besar, di mana setiap node masih merupakan mesin berperforma tinggi yang sama dengan prosesor tradisional.


Sementara itu, prosesor kompatibel x86 modern telah lama memasukkan serangkaian instruksi vektor yang mirip dengan GPU dalam tujuan dan prinsip operasi, tetapi mempertahankan rangkaian prosesor umum dalam gaya von Neumann secara keseluruhan. Saya tidak ragu bahwa setiap pendekatan yang cukup umum untuk komputasi akan dimasukkan dalam prosesor populer.


Ada pendapat otoritatif : masa depan terletak pada akselerator khusus yang dapat diprogram. Di bawah kepingan besi yang luar biasa seperti itu, sangat masuk akal untuk mengembangkan bahasa dengan semantik khusus. Tetapi komputer untuk keperluan umum masih dan mirip dengan PDP-11, yang bahasa C-like imperative sangat cocok.


C akan hidup


Ada kontradiksi mendasar dalam artikel Chiznell. Dia menulis bahwa untuk memastikan kecepatan program C, prosesor meniru mesin C abstrak (dan PDP-11 yang sudah lama terlupakan), setelah itu menunjukkan keterbatasan mesin tersebut. Tetapi saya tidak mengerti mengapa ini berarti bahwa "C bukan bahasa tingkat rendah."


Secara umum, ini bukan tentang kelemahan C sebagai bahasa, tetapi tentang kritik terhadap arsitektur gaya von Neumann dan model pemrograman yang mengikuti dari mereka. Namun sejauh ini tampaknya tidak ada industri yang siap untuk meninggalkan arsitektur yang sudah dikenal (setidaknya tidak pada prosesor untuk keperluan umum).


Terlepas dari ketersediaan banyak prosesor khusus seperti GPU dan TPU, arsitektur von Neumann saat ini dalam kendali dan industri membutuhkan bahasa yang memungkinkannya beroperasi pada tingkat serendah mungkin dalam kerangka arsitektur paling populer. Yang cukup sederhana, porting ke berbagai platform dan bahasa pemrograman terstandarisasi adalah C (dan keluarga terdekatnya).


Untuk semua itu, C memiliki kekurangan yang cukup: perpustakaan fungsi kuno, standar yang rumit dan tidak konsisten, dan kesalahan desain kasar. Tetapi, tampaknya, pencipta bahasa masih melakukan sesuatu yang benar.


Dengan satu atau lain cara, kita masih membutuhkan bahasa tingkat rendah, dan itu dibuat khusus untuk komputer Fonneimann yang populer. Dan biarkan C ketinggalan zaman, tetapi tampaknya, setiap penerusnya masih harus membangun prinsip yang sama.

Source: https://habr.com/ru/post/id465429/


All Articles