Welcome to the Concurrency Jungle

Yups. Seperti judul yang saya sebutkan. selamat datang di hutan rimba konkuren. Teknologi komputasi semakin lama semakin mature dan memberikan banyak tambahan-tambahan library kepada kita developer untuk membuat aplikasi kita menjadi lebih cepat, memanfaatkan kemampuan hardware multicore dsb. .NET tidak ada bedanya. Banyak pilihan yang ditawarkan sehingga kadang kita tidak tau lagi mana yang harus dipakai, apa bedanya dan akhirnya jadi tidak terpakai sama sekali.

Conccurency merupakan hal yang sangat diperlukan untuk masa sekarng ini. Jika tidak maka sayang sekali multicore processor yang tersedia di production server. Sudah mahal-mahal beli komputer super power. Tapi kita gak bisa manfaatin sebagai programmer. How come ?

Mari kita lihat apa-apa saja pilihan yang tersedia untuk kita para programmer .NET. Kita mulai dari primitive yang tersedia yaitu Thread.

Threading

Salah satu pertanyaan yang wajib ditanyakan ketika akan masuk ke perusahaan tempat saya bekerja (Petrolink Services Indonesia) adalah.

What's the difference between thread and process ? Do you know the answer ? If you know please send me your resume cause I'm dying to talk with you. :)

send to my email : welly dot tambunan at petrolink dot com

wait wait wait.. back to the topic..

ok. begini cara melihat perbedaan antara thread dan process di komputer anda. anda bisa mencari referensi yang sesuai untuk mendapat penjelasan yang lebih detail

Anda bisa mendapatkan panduan yang bagus dari Threading in C# untuk mendalami tentang Threading.

Thread Pool

Apakah thread sudah cukup untuk menyelesaikan masalah performance ? Tentu saja tidak. Bahkan jika kita tidak mengalokasikan thread dengan benar kita malah akan mendapat performance penalty. Thread itu mahal loh... Gak gratis. Jadi kita harus memanfaatkannya dengan benar. Sehingga kita memanfaatkan Thread Pool untuk mengatur thread tersebut. Sebelum .NET 4.0 kita mendapatkan kemudahan untuk memanfaatkan thread pool dengan Thread.QueueUserWorkItem. Tapi ini pun banyak keterbatasannya.

Task Parallel Library (TPL)

Pada .NET 4.0 kita mendapatkan kemudahan untuk mengatur Thread dengan Task Parallel Library ( TPL ). Disini kita diberikan tambahan kemudahan seperti Parallel LINQ, Konsep Continuation untuk kordinasi task dsb. This is very great. You should start exploring that now.

Jika anda perhatikan WinRT di Windows 8 anda tidak akan menemukan construct primitive seperti Threading dkk. Hal tersebut adalah by design untuk menghindarkan kita dari kesalahan dan memaksa kita untuk menggunakan konstruk dimana kita dituntun untuk berbuat sedikit kesalahan. That's great right ?

Jika anda ingin mendalami lagi maka anda dapat membaca panduang Parallel Programming with Microsoft .NET.

TPL in Action

Berikut contoh yang simple dan meaningless bagaimana parallel programming bisa getting the most dari multicore processor anda.

Ok Ok. Seperti yang saya katakan sebelumnya bahwa contohnya meaningless. Saya disini hanya ingin menunjukkan bahwa operasi yang dilakukan ini adalah single thread. Anda dapat mengganti DoComplicatedCalculation dengan operasi seperti enkripsi file, resize image, encoding video dsb. Hal2 berikut dapat dilakukan sebenarnya saling lepas satu sama lain. Anda tidak perlu menunggu satu file selesai di encrypt baru melakukan yang berikutnya. Tetapi mungkin kita sudah dari dulu terbawa pola berpikir sequential sehingga terbawa sampai sekarang. Berikut adalah rekaman CPU yang ada di laptop saya.

Anda dapat melihat bahwa CPU Utilization saya tidak maksimal. Sebenarnya proses tersebut dapat memanfaatkan semua kemampuan CPU yang saya miliki. Tetapi kenyataannya tidak. Ada 4 logical processor tetapi tidak digunakan secara maksimal. Sayang sekali processornya ya ?

Sekarang kita lihat perbandingannya dengan memanfaatkan TPL. Code yang berubah sangat simple sekali sebenarnya.

Tetapi hal yang dihasilkannya sangat significant.

Disini program kita memanfaatkan kemampuan maksimal dari processor. This is how we should use our resources. Ini alasan mengapa kita membeli hardware mahal, multicore dsb. Kita harus bisa getting the most of it. Right ?

Data Flow

Masih belum cukup ? Kita mendapatkan kemudahan lagi untuk melakukan parallell programing dengan Pipe And filter structure. Ini dapat kita lakukan dengan memanfaatkan Data Flow dari TPL. Jika kita memiliki data yang jumlahnya besar dan harus melalui beberapa proses untuk mentransformnya menjadi output tertentu. Kita tentu saja tidak akan menyesaikan satu potongan kemudia melanjutkan potongan yang lain bukan? Katakanlah kita ingin melakukan proses transformasi dari input file sehingga file tersebut terenkripsi dan terkompress dengan benar. Maka kita akan mendapatkan pipeline kira2 sebagai berikut.

Dalam setiap filter kita memiliki queue yang akan diproses oleh worker thread. Bentuknya sama seperti konsep Producer Consumer. But. hey. that's already made for us. Great...

Kita hanya fokus ke process yang perlu kita lakukan di block tersebut. Kita bisa memanfaatkannya juga untuk Audio/Video processing dsb. Banyak scenario yang bisa dilakukan dengan Data Flow berikut. Data Flow mempermudah kita untuk membangun parallel dan asyncrhonous pipeline.

Reactive Extensions

Asynchronous Programming Model (APM)

Sekarang kita beralih kedunia yang masih memanfaatkan thread juga tetapi bukan multithreading. Coba perhatikan gambar berikut. Pernahkah anda mengalami hal seperti ini ?

Aplikasi sederhana di atas tidak responsive dan akhirnya terminated dengan sempurna. Coba kita perhatikan code dibaliknya seperti apa.

Anda dapat melihat bahwa masalahnya method DownloadString merupakan operasi syncrhonous yang akan memblock UI thread, sehingga Window tidak dapat menerima user input lagi. Operasi DownloadString berhubungan dengan I/O dan sudah barang tentu kita tidak tahu kapan pastinnya operasi tersebut akan selesai. Tidak ada jaminan bahwa operasi tersebut cepat selesai. Dibalik layar sebenarnya operasi tersebut sudah ditangani oleh networking hardware. Sebenarnya UI thread sudah dapat dilepaskan dan kita tinggal menunggu hasilnya saja. Bagaimana cara melakukannya dengan benar ?

Sebelum .NET 4.5 kita mengenai beberapa construct untuk melakukan Asynchronous Programming model (APM). Salah satunya dengan memanfaatkan callback dari pasangan method Begin... dan End... Contohnya BeginGetRequestStream dan pasangannya BeginGetRequestStream dari kelas WebRequest. Masalahnya dengan construct ini adalah code kita menjadi sulit dibaca dan dimengerti alurnya.

Event Based Asynchronous Pattern (EAP)

Alternatif yang lain adalah dengan menggunakan Event-Based Asynchronous Pattern (EAP). Jadi kita tinggal meregister event handler yang akan dieksekusi ketika hasilnya sudah tersedia untuk dikonsumsi. Banyak pro dan kontra mengenap EAP ini. EAP memberikan kemudahan untuk UI programming karena mudah digunakan untuk user interface. Event akan di eksekusi pada thread ui. Tetapi masalah performance APM tentu saja lebih baik, karena EAP diimplementasikan dengan APM. Sehingga ada performance penalty. Untuk UI application mungkin baik digunakan. Tetapi untuk kebutuhan menulis server yang high performance tidak disarankan. Baca CLR via C#, Third Edition karangan Jeffrey Richter Chapter 27.

async/await

Pada .NET 4.5 dan C# 5 kita diberikan penyelesaian masalah tersebut dengan async/await construct. Fitur ini sangat luar biasa sekali. Tidak ada lagi callback dan code yang ada juga mudah dibaca. Tidak berbeda dengan code yang ditulis secara synchronous.

Semua statement yang ada setelah line dengan keyword await akan digenerate oleh kompiler sebagai callback. method ini tidak akan memblock UI thread. Clean and performance. This is how you should write your code in the future. :)


Anda dapat membaca penjelasan lebih lanjut mengenai hal ini di MSDN.

Untuk mendapatkan informasi terbaru dari sekitar dunia conccurency di .net programming anda dapat melihat di blog berikut

Parallel Programming with .NET

auto vectorize

Mari kita lihat dengan bahasa tetangga kita yaitu c++. c++ selalu dikenal dengan keunggulan di masalah performance. Dan di versi visual studio yang berikut nya hal ini dibantu lagi oleh kompiler. Seperti yang kita bahas dibagian yang sebelumnya bahwa performance dapat dicapai dengan melakukan hal-hal secara parallel ketimbang sequential. c++ menyediakan hal ini di level looping secara otomatis. Kompiler c++ akan secara otomatis melakukan vectorize terhadap perulangan (loop) jika dia bisa. Jadi statement loop tersebut akan di ubah oleh si compiler. Bisa lebih cepat 8 x. Fantastis. Ini tentu saja dapat dilakukan pada processor yang support SIMD.

Anda dapat membaca keterangan lebih jelas mengenai Vectorization dari artikel berikut ini

Auto-Vectorization
What is Vectorization?
Auto-Vectorizer in Visual Studio 11 - Overview
GoingNative 7: VC11 Auto-Vectorizer, C++ NOW, Lang.NEXT

Bagaimana dengan c# dan managed code yang lain ? Apakah kita mendapatkan kemewahan yang serupa ? Ternyata bukan hanya kita yang menanyakan hal tersebut.

This is sad. - -".

c++ amp

c++ amp meningkatkan kecepatan eksekusi dari code anda dengan memanfaatkan hardware GPU (Graphics Processing Unit) yang memiliki kemampuan data parallel. c++ amp memiliki support terhadap array multidimensi, indexing, dan juga memiliki library matematika. c++ amp memberikan abstraksi terhadap hardware yang terdapat di perangkat kita. c++ amp ini membutuhkan DirectX 11 untuk hasil yang maksimal.

Anda dapat melihat beberapa artikel berikut untuk menggali lebih dalam lagi.

C++ Accelerated Massive Parallelism (C++ AMP)

Jika anda ingin mendapatkan informasi terbaru sekitar perkembangan parallel di dunia native code anda dapat mengunjungi

Parallel Programming in Native Code

Anda dapat melihat pada blog tersebut bahwa c++ amp menjadi selebritis baru di dunia c++. :)

Apakah kita c# developer dapat memanfaatkan kekuatan c++ amp tersebut ? Di MetroApps ? We really need that right ?

Untungnya ada beberapa workaround. Berikut beberapa diantaranya.

How to use C++ AMP from C#
How to use C++ AMP from C# using WinRT

Finally

Seperti judul yang saya sampaikan bahwa ibarat hutan rimba, dunia concurrency tersebut luas sekali. Jika kita tidak mempersiapkan diri kita akan tersesat. Saya harap artikel ini bisa memberikan gambaran singkat dan menjadi pemicu untuk memperdalam dan mengaplikasikannya di project anda. Apalagi moto dari Windows 8 adalah Fast and Fluid. Jadi sepertinya responsive apps, high performance merupakan hal yang harus diperhatikan mulai dari sekarang. Saya sudah menunjukkan hutan yang perlu kita telusuri bersama. Mari kita taklukkan hutan tersebut mulai dari sekarang. :).

Let's explore, share and learn together.

Share this post: | | | |

Comments

No Comments