Concurrency, coroutine, mesin acara, ... matematika hidup

Komputasi paralel mempesona dengan perilaku yang tak terduga. Tetapi perilaku bersama dari proses tidak dapat diprediksi. Hanya dalam hal ini ia dapat dipelajari dan dipahami dalam kebiasaannya. Konkurensi multi-utas modern unik. Secara harfiah. Dan ini semua esensi buruknya . Esensi yang dapat dan harus dipengaruhi. Esensi, yang seharusnya, dalam cara yang baik, telah lama diubah ...

Meskipun ada opsi lain. Tidak perlu mengubah apa pun dan / atau memengaruhi sesuatu. Biarkan ada multithreading dan coroutine, biarkan saja ... dan pemrograman otomatis paralel (AP). Biarkan mereka bersaing dan, jika perlu dan mungkin, saling melengkapi. Dalam pengertian ini, paralelisme modern memiliki setidaknya satu nilai tambah - ini memungkinkan Anda untuk melakukan ini.

Nah, mari kita bersaing!?

1. Dari serial ke paralel


Pertimbangkan memprogram persamaan aritmatika yang paling sederhana:

C2 = A + B + A1 + B1; (1)

Biarkan ada blok yang menerapkan operasi aritmatika sederhana. Dalam hal ini, jumlah blok sudah cukup. Gagasan yang jelas dan akurat tentang jumlah balok, strukturnya dan hubungan di antara mereka memberi beras. 1. Dan pada Gambar. 2. konfigurasi VKP (a) media diberikan untuk menyelesaikan persamaan (1).

gambar
Fig. 1. Model proses

struktural Namun diagram struktural pada Gambar. 1 sesuai dengan sistem tiga persamaan:

= A + B;
C1 = A1 + B; (2)
C2 = C + C1;

Pada saat yang sama (2), ini adalah implementasi paralel dari persamaan (1), yang merupakan algoritma untuk menjumlahkan array angka, juga dikenal sebagai algoritma pengganda. Di sini array diwakili oleh empat angka A, B, A1, B1, variabel C dan C1 adalah hasil antara, dan C2 adalah jumlah array.

gambar
Fig. 2. Jenis dialog untuk konfigurasi tiga proses paralel.Fitur

implementasi termasuk kontinuitas operasinya, ketika setiap perubahan dalam data input mengarah ke penghitungan ulang hasil. Setelah mengubah data input, akan dibutuhkan dua siklus clock, dan ketika blok dihubungkan secara seri, efek yang sama akan dicapai dalam tiga siklus clock. Dan semakin besar array, semakin besar gain kecepatannya.

2. Concurrency sebagai masalah


Jangan heran jika Anda akan dipanggil banyak argumen yang mendukung solusi paralel tertentu, tetapi mereka akan diam tentang kemungkinan masalah yang sama sekali tidak ada dalam pemrograman berurutan biasa. Alasan utama untuk interpretasi yang sama dari masalah implementasi paralelisme yang benar. Mereka mengatakan sedikit tentangnya. Jika mereka mengatakannya. Kami akan menyentuhnya di bagian yang terkait dengan akses paralel ke data.

Setiap proses dapat direpresentasikan sebagai banyak langkah tak terpisahkan yang berurutan. Untuk banyak proses, pada setiap langkah seperti itu, tindakan milik semua proses dijalankan secara bersamaan. Dan di sini kita mungkin menghadapi masalah yang memanifestasikan dirinya dalam contoh dasar berikut.

Misalkan ada dua proses paralel yang sesuai dengan sistem persamaan berikut:

c = a + b; (3)
a = b + c;

Misalkan variabel a, b, c diberi nilai awal 1, 1, 0. Kita dapat berharap bahwa protokol perhitungan untuk lima langkah akan sebagai berikut:

a              b               c
1.000       1.000       0.000      
1.000       1.000       2.000       
3.000       1.000       2.000       
3.000       1.000       4.000       
5.000       1.000       4.000        
5.000       1.000       6.000   

Ketika membentuknya, kami melanjutkan dari fakta bahwa operator dieksekusi secara paralel (simultan) dan dalam satu ukuran diskrit (langkah). Untuk pernyataan berulang, itu akan menjadi iterasi dari loop. Kita juga dapat mengasumsikan bahwa dalam proses perhitungan variabel memiliki nilai-nilai tetap pada awal ukuran diskrit, dan perubahannya terjadi pada akhirnya. Ini cukup konsisten dengan situasi sebenarnya, ketika dibutuhkan beberapa waktu untuk menyelesaikan operasi. Ini sering dikaitkan dengan penundaan yang melekat pada blok yang diberikan.

Tetapi, kemungkinan besar, Anda akan mendapatkan sesuatu seperti protokol ini:

   a              b               c
1.000       1.000       0.000      
3.000       1.000       2.000       
5.000       1.000       4.000       
7.000       1.000       6.000       
9.000       1.000       8.000       
11.000     1.000     10.000       

Ini sama dengan pekerjaan dari proses yang mengeksekusi dua pernyataan berurutan dalam satu siklus:

c = a + b; a = b + c; (4)

Tetapi dapat terjadi bahwa eksekusi pernyataan akan persis sebaliknya, dan kemudian protokolnya adalah sebagai berikut:

   a              b               c
1.000       1.000       0.000      
1.000       1.000       2.000       
3.000       1.000       4.000       
5.000       1.000       6.000       
7.000       1.000       8.000       
9.000       1.000     10.000       

Dalam pemrograman multi-utas, situasinya bahkan lebih buruk. Dengan tidak adanya sinkronisasi proses, tidak hanya sulit untuk memprediksi urutan peluncuran operator, tetapi pekerjaan mereka juga akan terganggu di mana saja. Semua ini tidak lain mempengaruhi hasil kerja sama para operator.

Dalam kerangka teknologi AP, bekerja dengan variabel proses umum diizinkan secara sederhana dan benar. Di sini, paling sering, tidak diperlukan upaya khusus untuk menyinkronkan proses dan bekerja dengan data. Tetapi akan perlu untuk memilih tindakan yang akan dianggap kondisional instan dan tidak terpisahkan, serta membuat model proses otomatis. Dalam kasus kami, tindakan akan menjadi operator penjumlahan, dan automata dengan transisi siklik akan bertanggung jawab atas peluncurannya.
Listing 1 menunjukkan kode untuk proses yang mengimplementasikan operasi penjumlahan. Modelnya adalah mesin keadaan terbatas (lihat Gambar. 3) dengan satu keadaan dan transisi loop tanpa syarat, di mana satu-satunya tindakan y1, setelah melakukan operasi penjumlahan dua variabel, menempatkan hasilnya pada yang ketiga.

gambar
Fig. 3. Model otomatis operasi penjumlahan

Daftar 1. Implementasi proses otomat untuk operasi penjumlahan
#include "lfsaappl.h"
class FSumABC :
    public LFsaAppl
{
public:
    LFsaAppl* Create(CVarFSA *pCVF) { Q_UNUSED(pCVF)return new FSumABC(nameFsa); }
    bool FCreationOfLinksForVariables();
    FSumABC(string strNam);
    CVar *pVarA;		//
    CVar *pVarB;		//
    CVar *pVarC;		//
    CVar *pVarStrNameA;        //
    CVar *pVarStrNameB;        //
    CVar *pVarStrNameC;        //
protected:
    void y1();
};

#include "stdafx.h"
#include "FSumABC.h"

static LArc TBL_SumABC[] = {
    LArc("s1",	"s1","--", "y1"),
    LArc()
};

FSumABC::FSumABC(string strNam):
    LFsaAppl(TBL_SumABC, strNam, nullptr, nullptr)
{ }

bool FSumABC::FCreationOfLinksForVariables() {
    pVarA = CreateLocVar("a", CLocVar::vtBool, "variable a");
    pVarB = CreateLocVar("b", CLocVar::vtBool, "variable c");
    pVarC = CreateLocVar("c", CLocVar::vtBool, "variable c");
    pVarStrNameA = CreateLocVar("strNameA", CLocVar::vtString, "");
    string str = pVarStrNameA->strGetDataSrc();
    if (str != "") { pVarA = pTAppCore->GetAddressVar(pVarStrNameA->strGetDataSrc().c_str(), this); }
    pVarStrNameB = CreateLocVar("strNameB", CLocVar::vtString, "");
    str = pVarStrNameB->strGetDataSrc();
    if (str != "") { pVarB = pTAppCore->GetAddressVar(pVarStrNameB->strGetDataSrc().c_str(), this); }
    pVarStrNameC = CreateLocVar("strNameC", CLocVar::vtString, "");
    str = pVarStrNameC->strGetDataSrc();
    if (str != "") { pVarC = pTAppCore->GetAddressVar(pVarStrNameC->strGetDataSrc().c_str(), this); }
    return true;
}

void FSumABC::y1() { 
    pVarC->SetDataSrc(this, pVarA->GetDataSrc() + pVarB->GetDataSrc()); 
}


Penting, atau lebih tepatnya, bahkan perlu, di sini adalah penggunaan variabel lingkungan CPSU. "Sifat bayangan" mereka memastikan interaksi proses yang benar. Selain itu, lingkungan memungkinkan Anda untuk mengubah mode operasinya, tidak termasuk perekaman variabel dalam memori bayangan menengah. Analisis protokol yang diperoleh dalam mode ini memungkinkan kami untuk memverifikasi perlunya menggunakan variabel bayangan.

3. Dan coroutine? ...


Akan menyenangkan untuk mengetahui bagaimana coroutine yang diwakili oleh bahasa Kotlin akan mengatasi tugas tersebut. Mari kita ambil sebagai templat solusi yang dipertimbangkan program dalam diskusi [1]. Ini memiliki struktur yang mudah direduksi menjadi tampilan yang diperlukan. Untuk melakukan ini, ganti variabel logis di dalamnya dengan tipe numerik dan tambahkan variabel lain, dan alih-alih operasi logis kita akan menggunakan operasi penjumlahan. Kode yang sesuai ditunjukkan dalam daftar 2.

Listing 2. Program penjumlahan paralel Kotlin
import kotlinx.coroutines.*

suspend fun main() =
    // Structured concurrency: if any child coroutine fails,
    // everything else will be cancelled
    coroutineScope {
        var a = 1
        var b = 1
        var c = 0;
        // Use default thread pool 
        withContext(Dispatchers.Default) {
            for (i in 0..4) {
               var res = listOf(async { a+b }, async{ b+c }).map { it.await() }
			c = res[0]
			a = res[1]
               println("$a, $b, $c")
            }
        }
    }


Tidak ada pertanyaan tentang hasil dari program ini, seperti itu persis cocok dengan yang pertama dari protokol di atas.

Namun, konversi kode sumber tidak sejelas kelihatannya, karena Tampaknya wajar untuk menggunakan fragmen kode berikut:

listOf(async {  = a+b }, async{  = b+c })

Seperti yang ditunjukkan oleh pengujian (ini dapat dilakukan online di situs web Kotlin - kotlinlang.org/#try-kotlin ), penggunaannya mengarah ke hasil yang sama sekali tidak dapat diprediksi, yang juga berubah dari peluncuran ke peluncuran. Dan hanya analisis yang lebih cermat dari program sumber yang mengarah ke kode yang benar.

Kode yang berisi kesalahan dari sudut pandang fungsi program, tetapi sah dari sudut pandang bahasa, membuat kita takut akan keandalan program di dalamnya. Pendapat ini, mungkin, dapat ditentang oleh para ahli Kotlin. Namun demikian, kemudahan melakukan kesalahan, yang tidak dapat dijelaskan hanya dengan kurangnya pemahaman tentang "pemrograman coroutine," tetap mendorong kesimpulan seperti itu.

4. Mesin acara di Qt


Sebelumnya, kami menetapkan bahwa automaton peristiwa bukanlah automaton dalam definisi klasiknya. Dia baik atau buruk, tetapi sampai batas tertentu, mesin acara masih relatif dari mesin klasik. Apakah jauh, dekat, tetapi kita harus membicarakannya secara langsung sehingga tidak ada kesalahpahaman tentang ini. Kami mulai membicarakan hal ini dalam [2], tetapi semuanya untuk melanjutkannya. Sekarang kita akan melakukan ini dengan memeriksa contoh lain dari penggunaan mesin acara di Qt.

Tentu saja, automaton peristiwa dapat dianggap sebagai kasus degenerasi automaton klasik dengan durasi siklus tidak pasti dan / atau variabel yang terkait dengan suatu peristiwa. Kemungkinan penafsiran seperti itu ditunjukkan dalam artikel sebelumnya ketika hanya memecahkan satu dan, apalagi, contoh yang agak spesifik (lihat detail [2]). Selanjutnya, kami akan mencoba menghilangkan kesenjangan ini.

Perpustakaan Qt hanya mengaitkan transisi mesin dengan peristiwa, yang merupakan batasan serius. Misalnya, dalam bahasa UML yang sama, transisi dikaitkan tidak hanya dengan peristiwa yang disebut peristiwa awal, tetapi juga dengan kondisi perlindungan - ekspresi logis yang dihitung setelah acara diterima [3]. Dalam MATLAB, situasinya lebih dimitigasi dan terdengar seperti ini: "jika nama acara tidak ditentukan, maka transisi akan terjadi ketika ada peristiwa yang terjadi" [4]. Tetapi di sana-sini, akar penyebab transisi adalah peristiwa. Tetapi bagaimana jika tidak ada acara?

Jika tidak ada acara, maka ... Anda dapat mencoba membuatnya. Daftar 3 dan Gambar 4 mendemonstrasikan bagaimana melakukan ini, menggunakan turunan dari kelas otomat LFsaAppl dari lingkungan VKPa sebagai "pembungkus" dari event Qt-class. Di sini, aksi y2 dengan periodisitas waktu diskrit dari ruang otomat mengirimkan sinyal yang memulai dimulainya transisi otomat Qt. Yang terakhir, menggunakan metode s0Exited, memulai aksi y1, yang mengimplementasikan operasi penjumlahan. Perhatikan bahwa mesin acara dibuat oleh tindakan y3 secara ketat setelah memeriksa inisialisasi variabel lokal dari kelas LFsaAppl.

gambar
Fig. 4. Kombinasi mesin klasik dan acara

Listing 3. Menerapkan model penjumlahan dengan robot acara
#include "lfsaappl.h"
class QStateMachine;
class QState;

class FSumABC :
    public QObject,
    public LFsaAppl
{
    Q_OBJECT
...
protected:
    int x1();
    void y1(); void y2(); void y3(); void y12();
signals:
    void GoState();
private slots:
    void s0Exited();
private:
    QStateMachine * machine;
    QState * s0;
};

#include "stdafx.h"
#include "FSumABC.h"
#include <QStateMachine>
#include <QState>

static LArc TBL_SumABC[] = {
    LArc("st",	"st","^x1",	"y12"),
    LArc("st",	"s1","x1",	"y3"),
    LArc("s1",	"s1","--",	"y2"),
    LArc()
};

FSumABC::FSumABC(string strNam):
    QObject(),
    LFsaAppl(TBL_SumABC, strNam, nullptr, nullptr)
{ }
...
int FSumABC::x1() { return pVarA&&pVarB&&pVarC; }

void FSumABC::y1() {
    pVarC->SetDataSrc(this, pVarA->GetDataSrc() + pVarB->GetDataSrc());
}
//
void FSumABC::y2() { emit GoState(); }
//
void FSumABC::y3() {
    s0 = new QState();
    QSignalTransition *ps = s0->addTransition(this, SIGNAL(GoState()), s0);
    connect (s0, SIGNAL(entered()), this, SLOT(s0Exited()));
    machine = new QStateMachine(nullptr);
    machine->addState(s0);
    machine->setInitialState(s0);
    machine->start();
}
//    
void FSumABC::y12() { FInit(); }

void FSumABC::s0Exited() { y1(); }


Di atas, kami menerapkan mesin yang sangat sederhana. Atau, lebih tepatnya, kombinasi robot klasik dan acara. Jika implementasi sebelumnya dari kelas FSumABC diganti dengan yang dibuat, maka tidak akan ada perbedaan dalam aplikasi. Tetapi untuk model yang lebih kompleks, sifat terbatas automata yang dikendalikan oleh peristiwa mulai memanifestasikan diri mereka sepenuhnya. Minimal, sudah dalam proses membuat model. Listing 4 menunjukkan implementasi model elemen AND-NOT dalam bentuk automaton peristiwa (untuk rincian lebih lanjut tentang model automaton elemen AND-NOT yang digunakan, lihat [2]).

Daftar 4. Menerapkan model elemen DAN TIDAK oleh mesin acara
#include <QObject>

class QStateMachine;
class QState;

class MainWindow;
class ine : public QObject
{
    Q_OBJECT
public:
    explicit ine(MainWindow *parent = nullptr);
    bool bX1, bX2, bY;
signals:
    void GoS0();
    void GoS1();
private slots:
    void s1Exited();
    void s0Exited();
private:
    QStateMachine * machine;
    QState * s0;
    QState * s1;
    MainWindow *pMain{nullptr};
friend class MainWindow;
};

#include "ine.h"
#include <QStateMachine>
#include <QState>
#include "mainwindow.h"
#include "ui_mainwindow.h"

ine::ine(MainWindow *parent) :
    QObject(parent)
{
    pMain = parent;
    s0 = new QState();
    s1 = new QState();

    s0->addTransition(this, SIGNAL(GoS1()), s1);
    s1->addTransition(this, SIGNAL(GoS0()), s0);

    connect (s0, SIGNAL(entered()), this, SLOT(s0Exited()));
    connect (s1, SIGNAL(entered()), this, SLOT(s1Exited()));


    machine = new QStateMachine(nullptr);
    machine->addState(s0);
    machine->addState(s1);
    machine->setInitialState(s1);
    machine->start();
}

void ine::s1Exited() {
    bY = !(bX1&&bX2);
    pMain->ui->checkBoxY->setChecked(bY);
}

void ine::s0Exited() {
    bY = !(bX1&&bX2);
    pMain->ui->checkBoxY->setChecked(bY);
}


Menjadi jelas bahwa event automata di Qt didasarkan sepenuhnya pada Moore automata. Ini membatasi kemampuan dan fleksibilitas model, seperti tindakan hanya dikaitkan dengan negara. Akibatnya, misalnya, tidak mungkin untuk membedakan antara dua transisi dari keadaan 0 ke 1 untuk otomat yang ditunjukkan pada Gambar. 4 dalam [2].

Tentu saja, untuk mengimplementasikan Miles, Anda dapat menggunakan prosedur terkenal untuk beralih ke mesin Moore. Tapi ini mengarah pada peningkatan jumlah negara dan menghilangkan asosiasi sederhana, visual dan berguna negara model dengan hasil aksinya. Sebagai contoh, setelah transformasi tersebut, dua keadaan otomat Moore harus dicocokkan dengan keadaan tunggal dari output model 1 dari [2].

Pada model yang lebih kompleks, masalah dengan kondisi transisi mulai muncul dengan jelas. Untuk menyiasatinya untuk implementasi perangkat lunak dari elemen AND-NOT yang sedang dipertimbangkan, analisis keadaan saluran input dimasukkan ke dalam dialog kontrol model, seperti yang ditunjukkan pada Listing 5.

Daftar 5. Dialog kontrol elemen NAND
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "ine.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    pine = new ine(this);
    connect(this, SIGNAL(GoState0()), pine, SIGNAL(GoS0()));
    connect(this, SIGNAL(GoState1()), pine, SIGNAL(GoS1()));
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_checkBoxX1_clicked(bool checked)
{
    bX1 = checked;
    pine->bX1 = bX1;
    bY = !(bX1&&bX2);
    if (!(bX1&&bX2)) emit GoState0();
    else emit GoState1();
}

void MainWindow::on_checkBoxX2_clicked(bool checked)
{
    bX2 = checked;
    pine->bX2 = bX2;
    bY = !(bX1&&bX2);
    if (!(bX1&&bX2)) emit GoState0();
    else emit GoState1();
}


Singkatnya, semua hal di atas jelas merumitkan model dan menciptakan masalah dengan memahami kerjanya. Selain itu, solusi lokal tersebut mungkin tidak berfungsi ketika mempertimbangkan komposisi dari mereka. Contoh yang baik dalam kasus ini adalah upaya untuk membuat model pemicu RS (untuk detail lebih lanjut tentang model dua komponen otomat pemicu RS lihat [5]). Namun, kesenangan dari hasil yang dicapai akan dikirimkan ke penggemar mesin acara. Jika ... kecuali, tentu saja, mereka berhasil;)

5. Fungsi kuadratik dan ... kupu-kupu?


Lebih mudah mewakili data input sebagai proses paralel eksternal. Di atas ini adalah dialog untuk mengelola model elemen AND-NOT. Selain itu, laju perubahan data dapat secara signifikan mempengaruhi hasilnya. Untuk mengonfirmasi hal ini, kami mempertimbangkan perhitungan fungsi kuadratik y = ax² + bx + c, yang kami implementasikan dalam bentuk serangkaian blok yang berfungsi paralel dan berinteraksi.

Grafik fungsi kuadratik diketahui memiliki bentuk parabola. Tetapi parabola yang digambarkan oleh ahli matematika dan parabola bahwa osiloskop, misalnya, akan ditampilkan, sebenarnya, tidak akan pernah cocok. Alasan untuk ini adalah bahwa ahli matematika sering berpikir dalam kategori instan, percaya bahwa perubahan dalam kuantitas input segera mengarah ke perhitungan fungsi. Tetapi dalam kehidupan nyata ini sama sekali tidak benar. Tampilan grafik fungsi akan tergantung pada kecepatan kalkulator, pada tingkat perubahan data input, dll. dll. Ya, dan program-program itu sendiri untuk kecepatan mungkin berbeda satu sama lain. Faktor-faktor ini akan mempengaruhi bentuk fungsi, dalam bentuk yang dalam situasi tertentu akan sulit untuk menebak parabola. Kami akan diyakinkan tentang ini lebih lanjut.

Jadi, kita tambahkan ke blok penjumlahan blok perkalian, pembagian, dan eksponensial. Memiliki set seperti itu, kita dapat "mengumpulkan" ekspresi matematika dari segala kompleksitas. Tetapi kita juga dapat memiliki "kubus" yang mengimplementasikan fungsi yang lebih kompleks. Fig. 5. implementasi fungsi kuadrat ditunjukkan dalam dua versi - multi-blok (lihat panah dengan label - 1, dan juga Gambar. 6) dan varian dari satu blok (pada Gambar. 5 panah dengan label 2).

gambar
Gbr.5. Dua opsi untuk mengimplementasikan fungsi kuadrat

gambar
Gambar. 6. Model struktural untuk menghitung fungsi kuadratik

Itu dalam gambar 5. tampaknya "kabur" (lihat panah bertanda 3), ketika diperbesar dengan benar (lihat grafik (tren), bertanda 4), yakin bahwa masalahnya tidak ada di properti grafik. Ini adalah hasil dari pengaruh waktu pada perhitungan variabel: variabel y1 adalah nilai output dari varian multi-blok (warna merah grafik) dan variabel y2 adalah nilai output dari varian single-block (warna hitam). Tetapi kedua grafik ini berbeda dari "grafik abstrak" [y2 (t), x (t-1)] (hijau). Yang terakhir dibangun untuk nilai variabel y2 dan nilai variabel input tertunda oleh satu siklus clock (lihat variabel dengan nama x [t-1]).

Dengan demikian, semakin tinggi laju perubahan fungsi input x (t), semakin kuat "efek kabur" akan dan semakin jauh grafik y1, y2 akan berasal dari grafik [y2 (t), x (t-1)]. "Cacat" yang terdeteksi dapat digunakan untuk tujuan Anda sendiri. Sebagai contoh, tidak ada yang mencegah kita dari menerapkan sinyal sinusoidal ke input. Kami akan mempertimbangkan opsi yang lebih rumit, ketika koefisien pertama dari persamaan juga berubah dengan cara yang sama. Hasil percobaan menunjukkan layar media VKPa, ditunjukkan pada Gambar. 7.

gambar
Gbr. 7. Hasil simulasi dengan sinyal input sinusoidal

Layar di kiri bawah menunjukkan sinyal yang disuplai ke input realisasi fungsi kuadratik. Di atasnya adalah grafik dari nilai-nilai output y1 dan y2. Bagan dalam bentuk "sayap" adalah nilai yang diplot dalam dua koordinat. Jadi, dengan bantuan berbagai realisasi fungsi kuadratik, kami menggambar setengah dari "kupu-kupu". Untuk menggambar keseluruhan adalah masalah teknologi ...

Tetapi paradoks paralelisme tidak berakhir di sana. Dalam gbr. Gambar 8 menunjukkan tren dalam perubahan "terbalik" dari variabel independen x. Mereka sudah lewat di sebelah kiri grafik "abstrak" (yang terakhir, kami perhatikan, belum mengubah posisinya!).

gambar
Ara. 8. Jenis grafik dengan perubahan linear langsung dan terbalik dari sinyal input

Dalam contoh ini, kesalahan "ganda" dari sinyal keluaran sehubungan dengan nilai "sesaat" menjadi jelas. Dan semakin lambat sistem komputasi atau semakin tinggi frekuensi sinyal, semakin besar kesalahannya. Gelombang sinus adalah contoh perubahan maju dan mundur dari sinyal input. Karena ini, "sayap" pada Gambar. 4 mengambil bentuk ini. Tanpa efek "kesalahan mundur", mereka akan menjadi dua kali lebih sempit.

6. Kontroler PID Adaptif


Mari kita pertimbangkan satu contoh lagi di mana masalah yang diperlihatkan ditampilkan. Dalam gbr. Gambar 9 menunjukkan konfigurasi medium VKP (a) saat memodelkan kontroler PID adaptif. Diagram blok juga ditampilkan di mana kontroler PID diwakili oleh unit bernama PID. Pada tingkat kotak hitam, ini mirip dengan implementasi fungsi kuadratik satu blok yang sebelumnya dianggap.

Hasil membandingkan hasil perhitungan model pengontrol PID dalam paket matematika tertentu dan protokol yang diperoleh dari hasil simulasi di lingkungan VKP (a) ditunjukkan pada Gambar. 10, di mana grafik merah adalah nilai yang dihitung, dan grafik biru adalah protokol. Alasan ketidakcocokan mereka adalah bahwa perhitungan dalam kerangka paket matematika, seperti yang ditunjukkan oleh analisis lebih lanjut, sesuai dengan operasi berurutan objek ketika mereka pertama kali bekerja di luar pengontrol PID dan berhenti, dan kemudian model objek, dll. dalam lingkaran. Lingkungan VKPa mengimplementasikan / memodelkan operasi paralel dari objek sesuai dengan situasi nyata, ketika model dan objek bekerja secara paralel.

gambar
Gambar 9. Implementasi pengontrol PID

gambar
Gambar. 10. Perbandingan nilai yang dihitung dengan hasil simulasi pengontrol PID

Karena, seperti yang telah kami umumkan, dalam VKP (a) terdapat mode untuk mensimulasikan operasi sekuensial blok struktural, tidaklah sulit untuk memverifikasi hipotesis mode perhitungan berurutan dari pengontrol PID. Mengubah mode operasi medium ke serial, kita mendapatkan kebetulan grafik, seperti yang ditunjukkan pada Gambar. 11.

gambar
Fig. 11. Operasi berurutan dari pengontrol PID dan objek kontrol

7. Kesimpulan


Di dalam kerangka kerja CPSU (a), model komputasi memberkahi program dengan properti yang merupakan karakteristik dari objek "hidup" nyata. Oleh karena itu asosiasi kiasan dengan "matematika hidup". Seperti yang diperlihatkan oleh praktik, kita dalam model diwajibkan untuk memperhitungkan apa yang tidak dapat diabaikan dalam kehidupan nyata. Dalam komputasi paralel, ini terutama waktu dan keterbatasan perhitungan. Tentu saja, sementara tidak melupakan kecukupan model matematika [otomatis] untuk satu atau "objek hidup" yang lain.

Tidak mungkin untuk melawan apa yang tidak bisa dikalahkan. Ini tentang waktu. Ini hanya mungkin dalam dongeng. Tetapi masuk akal untuk memperhitungkannya dan / atau bahkan menggunakannya untuk tujuan Anda sendiri. Dalam pemrograman paralel modern, mengabaikan waktu menyebabkan banyak masalah yang sulit dikendalikan dan dideteksi - balap sinyal, proses kebuntuan, masalah dengan sinkronisasi, dll. dll. VKP (a) teknologi sebagian besar bebas dari masalah seperti itu hanya karena itu termasuk model real-time dan memperhitungkan keterbatasan proses komputasi. Ini berisi apa yang sebagian besar analognya diabaikan.

Kesimpulannya. Kupu-kupu adalah kupu-kupu, tetapi Anda dapat, misalnya, mempertimbangkan sistem persamaan fungsi kuadrat dan linier. Untuk melakukan ini, cukup menambahkan ke model yang sudah dibuat model fungsi linier dan proses yang mengontrol kebetulan mereka. Jadi solusinya akan ditemukan oleh pemodelan. Kemungkinan besar tidak seakurat analitis, tetapi akan diperoleh lebih sederhana dan cepat. Dan dalam banyak kasus ini lebih dari cukup. Dan menemukan solusi analitis, biasanya, merupakan pertanyaan terbuka.
Sehubungan dengan yang terakhir, AVM ditarik. Bagi mereka yang tidak up to date atau lupa, - komputer analog. Prinsip-prinsip struktural pada umumnya banyak, dan pendekatan untuk menemukan solusi.

aplikasi


1) Video : youtu.be/vf9gNBAmOWQ

2) Arsip contoh : github.com/lvs628/FsaHabr/blob/master/FsaHabr.zip .

3) Arsip pustaka Qt dll yang diperlukan versi 5.11.2 : github.com/lvs628/FsaHabr/blob/master/QtDLLs.zip

Contoh dikembangkan di lingkungan Windows 7. Untuk menginstalnya, buka contoh arsip dan jika Anda belum menginstal Qt atau versi Qt saat ini berbeda dari versi 5.11.2, kemudian buka juga arsip Qt dan tulis path ke pustaka di variabel lingkungan Path. Selanjutnya, jalankan \ FsaHabr \ VCPaMain \ release \ FsaHabr.exe dan gunakan dialog untuk memilih direktori konfigurasi contoh, misalnya, \ FsaHabr \ 9.ParallelOperators \ Heading1 \ Pict1.C2 = A + B + A1 + B1 \ (lihat juga video).

Komentar. Pada awal pertama, alih-alih dialog pemilihan direktori, dialog pemilihan file mungkin muncul. Kami juga memilih direktori konfigurasi dan beberapa file di dalamnya, misalnya, vSetting.txt. Jika dialog pemilihan konfigurasi tidak muncul sama sekali, maka sebelum memulai, hapus file ConfigFsaHabr.txt di direktori tempat file FsaHabr.exe berada.

Agar tidak mengulangi pemilihan konfigurasi dalam dialog "kernel: otomatis spasi" (dapat dibuka menggunakan item menu: FSA-tools / Space Management / Management), klik tombol "ingat direktori path" dan hapus centang "tampilkan dialog pemilihan konfigurasi saat startup ". Di masa depan, untuk memilih konfigurasi yang berbeda, pilihan ini perlu diatur lagi.

literatur


1. NPS, conveyor, komputasi otomatis, dan lagi ... coroutine. [Sumber daya elektronik], mode akses: habr.com/en/post/488808 gratis. Yaz. Rusia (tanggal perawatan 02.22.2020).
2. Apakah mesin otomatis merupakan hal yang penting? [Sumber daya elektronik], mode akses: habr.com/en/post/483610 gratis. Yaz. Rusia (tanggal perawatan 02.22.2020).
3. BUCH G., RAMBO J., JACOBSON I. UML. Panduan pengguna. Edisi kedua. Akademi TI: Moskow, 2007 .-- 493 hal.
4. Rogachev G.N. Stateflow V5. Panduan pengguna. [Sumber daya elektronik], mode akses: bourabai.kz/cm/stateflow.htm gratis. Yaz. Rusia (tanggal sirkulasi 10.04.2020).
5.Model Komputasi Paralel [Sumber daya elektronik], mode akses: habr.com/en/post/486622 gratis. Yaz. Rusia (tanggal sirkulasi 04/11/2020).

All Articles