Bagaimana Formulasi Intertangle
Dua subsistem memulai hidup sebagai modul independen. Selama waktu, setiap subsistem mengumpulkan lapangan pada objek tuhan bersama: struktur konfigurasi global, manajer singleton, kelas statis. Setiap tambahan: benar dalam isolasi. Keterkaitan: tidak terlihat dalam pengujian skala kecil.
Tiga substrat di mana ini mengeras:
VLC pemutar media. Audio, video, & playlist membagi kunci yang melindungi state pemain global. Permintaan skip-to-timestamp mengambil kunci, memodifikasi posisi pemutaran, & membuang buffer audio. Subsistem video, menunggu kunci yang sama, berhenti. Subsistem playlist, juga menunggu, tidak dapat memprefetch. Hasil: tiga subsistem independen yang diserialkan melalui objek state yang sama. Biaya kinerja: O(N) konten lock di mana N = jumlah subsistem, semua proporsional terhadap latency operasi.
Loop acara Redis. AOF fsync (tulis disk), replikasi (tulisan jaringan), & eksekusi perintah (CPU) membagi loop acara tunggal. Setiap: benar dalam isolasi. Fsync lambat memperlambat eksekusi perintah. Lag replikasi berkembang di bawah beban tulis. Titik keterkaitan: konteks eksekusi tunggal yang dibagikan oleh operasi dengan profil latency yang berbeda.
LevelDB VersionSet. Jalur tulis (memtable flush) & kompakkan latar belakang membagi kunci VersionSet. Tugas kompakkan menahan kunci untuk ratusan milidetik. Jalur tulis berhenti. Kedua operasi: diperlukan. Keterkaitan: struktural, bukan masalah waktu.
Perbedaan Kritikal
Intertangle memiliki keterkaitan struktural, bukan masalah waktu. Masalah balap: dua thread mengakses state bersama tanpa sinkronisasi. Solusi: tambahkan kunci mutex.
Intertangle: dua subsistem membagi state oleh desain. Menambahkan kunci mutex tidak memperbaiki keterkaitan; itu serializes akses. Subsistem masih membagi state. Botol leher menyempit.
Menambahkan kunci mutex pada Intertangle VLC membuatnya lebih buruk: sekarang audio, video, & playlist semua menunggu kunci yang sama. Solusi struktural: berikan setiap subsistem state yang berbeda. Snapshot fase: beku snapshot state bersama pada batas fase, biarkan setiap subsistem membaca snapshot secara independen, gabungkan kembali tulisan pada akhir.
Struktural vs Waktu
Pertanyaan diagnostik utama untuk Intertangle: apakah menambahkan mutex akan memperbaiki masalah atau malah memperburuknya?
Kondisi balik: menambahkan mutex memperbaiki masalah. Pengaturan akses yang benar menghilangkan kerusakan.
Sebuah Intertangle: menambahkan mutex serializes akses tetapi mempertahankan keterkaitan struktural. Subsistem-subsistem masih membagikan state. Di bawah beban, mereka masih menghalangi satu sama lain. Botol kemacetan menyempit.
Bagaimana Mencari Intertangle
Tiga indikator deteksi:
1. Lapangan mutable yang dibagikan antar subsistem. Objek Tuhan dengan lapangan yang dibaca & ditulis oleh lebih dari satu subsistem. Jika menghapus akses lapangan subsistem memperbaiki subsistem lain, mereka membagikan state.
2. Kunci tunggal yang melindungi operasi yang tidak terkait. Satu kunci melindungi flush audio DAN decode video DAN pengambilan playlist: tiga subsistem dengan profil latency yang berbeda, semua menunggu satu sama lain. Bau: operasi yang tidak terkait di bawah nama kunci yang sama.
3. Keterbelakangan performa saat menambahkan beban. Latensi untuk operasi A meningkat saat operasi B berjalan secara koncurrent, meskipun A & B tampaknya independen. Mereka tidak independen: mereka membagikan state.
Perbaikan Snapshot Fase
Polanya snapshot fase:
# SEBELUM: subsistem membaca dan menulis state yang dibagikan secara langsung
class GameWorld:
position = {} # mutable yang dibagikan
velocity = {} # mutable yang dibagikan
def physics_tick(world):
for entity in world.entities:
world.position[entity] += world.velocity[entity] # menulis ke state bersama di tengah loop
# SETELAH: snapshot dibekukan sebelum fase; tulisan pergi ke buffer next_state
def physics_tick(world):
snapshot = world.freeze() # view immutable
next_state = {}
for entity in snapshot.entities:
next_state[entity] = snapshot.position[entity] + snapshot.velocity[entity]
world.merge(next_state) # menggabungkan atomik di batas fase
Setiap subsistem membaca snapshot. Tidak ada subsistem yang menulis ke snapshot. Tulisan terkumpul di buffer & digabungkan atomik di batas fase. Subsistem sekarang dieksekusi secara independen: tidak ada kontensi kunci, tidak ada ketergantungan urutan, tidak ada keterkaitan tersembunyi.
Terapkan Perbaikan
Sebuah tim melaporkan kecacatan: animasi sistem game engine & sistem tabrakan keduanya menulis ke objek transformasi entitas yang bersama. Ketika keduanya dieksekusi dalam tick yang sama, hasil tabrakan tergantung pada apakah animasi berjalan terlebih dahulu. Menambahkan mutex memperbaiki urutan, tetapi sekarang animasi mengalami hambatan saat sistem tabrakan menjalankan sweep broad-phase.