Python GIL'i erken çıkarma girişimi kötü performansla sonuçlandı: Neden?


13

Python yaratıcısı Guido Van Rossum'un bu yayını , GIL'i Python'dan kaldırmak için erken bir girişimden bahsediyor:

Bu daha önce hayal kırıklığı yaratan sonuçlarla denendi, bu yüzden kendim için çok çaba göstermeye isteksizim. 1999 yılında Greg Stein (Mark Hammond ile birlikte), GIL'i kaldıran ve tüm değiştirilebilir veri yapılarında ince taneli kilitlerle değiştirilen bir Python (1.5 inanıyorum) çatalı üretti. Ayrıca kabul edilebilir küresel değişken veri yapılarına olan birçok güveni kaldıran yamalar gönderdi. Bununla birlikte, kıyaslamadan sonra, en hızlı kilitleme ilkeli (o sırada Windows) olan platformda bile, tek iş parçacıklı yürütmeyi neredeyse iki kat yavaşlattığı, yani iki CPU'da biraz daha fazla iş alabileceğiniz gösterilmiştir. GIL olmadan tek bir CPU yerine GIL olmadan yapılır. Bu yeterli değildi ve Greg'in yaması unutulmaya başladı. (Greg'in performans hakkındaki yazısına bakın.)

Gerçek sonuçlarla pek tartışamıyorum, ama bunun neden olduğunu gerçekten merak ediyorum. Muhtemelen, GIL'nin CPython'dan çıkarılmasının çok zor olmasının ana nedeni, referans sayma bellek yönetim sisteminden kaynaklanmaktadır. Tipik bir Python programı arayacak Py_INCREFve Py_DECREFbinlerce veya milyonlarca kez, kilitleri etrafına sararsak, onu kilit bir tartışma noktası haline getirecektir.

Ancak, atomik ilkellerin eklenmesinin neden tek bir dişli programını yavaşlattığını anlamıyorum . Her bir Python nesnesindeki refcount değişkeni atomik bir ilkel olacak şekilde CPython'u yeni değiştirdiğimizi varsayalım. Ve sonra sadece referans sayısını arttırmamız gerektiğinde atomik bir artış (getirme ve ekleme talimatı) yaparız. Bu, Python referans sayımını iş parçacığı açısından güvenli hale getirir ve tek iş parçacıklı bir uygulamada herhangi bir performans cezası olmamalıdır, çünkü kilit çekişmesi olmayacaktır.

Ama ne yazık ki, benden daha akıllı olan birçok insan denedi ve başarısız oldu, bu yüzden açıkçası burada bir şey eksik. Bu probleme bakmamın nesi yanlış?


1
Yeniden senkronizasyon işleminin senkronizasyon gerektiren tek yer olmayacağını unutmayın. Alıntı, her liste ve sözlük nesnesi için en azından bir muteks içerdiğini düşündüğüm "tüm değişken veri yapılarında ince taneli kilitler" den bahsediyor. Ayrıca, atomik tamsayı işlemlerinin çekişmeye bakılmaksızın atomik olmayan eşdeğer kadar verimli olduğunu düşünmüyorum, bunun için bir kaynağınız var mı?

çünkü atomik işlemler atomik olmayan eşdeğerlerden daha yavaştır. Tek bir talimat olması, kaputun altında önemsiz olduğu anlamına gelmez. Biraz tartışma için bunu görün
Móż

Yanıtlar:


9

Greg Stein Python çatalına aşina değilim, bu yüzden isterseniz bu karşılaştırmayı spekülatif tarihsel analoji olarak indirim. Ancak bu, tekli ve çok iş parçacıklı uygulamalardan çok sayıda altyapı kod tabanının tarihsel deneyimiydi .

Temelde 1990'larda okuduğum her Unix uygulaması - AIX, DEC OSF / 1, DG / UX, DYNIX, HP-UX, IRIX, Solaris, SVR4 ve SVR4 MP - hepsi bu türden " ince taneli kilitleme - şimdi daha yavaş !! " sorun. Takip ettiğim DBMS'ler - DB2, Ingres, Informix, Oracle ve Sybase - hepsi de bunlardan geçti.

Milyonlarca kez "tek iş parçacıklı çalıştırdığımızda bu değişikliklerin bizi yavaşlatmayacağını" duydum. Asla bu şekilde çalışmaz. Koşullu olarak kontrol etmenin basit eylemi "çok iş parçacıklı çalışıyor muyuz, çalışmıyor muyuz?" özellikle yüksek düzeyde boru hatlı CPU'larda gerçek yükü artırır. Paylaşılan veri yapılarının bütünlüğünün sık sık çağrılmasını sağlamak için atom işlemleri ve ara sıra döndürme kilitleri eklendi ve çok yavaşlar. Birinci nesil kilit / senkronizasyon ilkeleri de yavaştı. Çoğu uygulama ekibi, çeşitli yerlerde ne kadar kenetlenme korumasına ihtiyaç duyulduğuna bağlı olarak, çeşitli "güçlü" düzeylerde birkaç ilkel sınıf ekler. Daha sonra, ilkel kilitleme ilkelerini nerede tokatladılar, gerçekten doğru yer olmadığını fark ettiler, bu yüzden profil bulmak, bulunan darboğazları tasarlamak, ve sistematik olarak roto-till. Bu yapıştırma noktalarının bazıları sonunda OS veya donanım hızlandırması aldı, ancak tüm evrim 3-5 yıl sürdü, minimum. Bu arada, MP veya MT versiyonları performans açısından zordu.

Aksi takdirde, sofistike kalkınma ekipleri, bu yavaşlamaların temel olarak kalıcı, inatçı bir yaşam olgusu olduğunu savunmuşlardır. IBM, örneğin SMP'yi etkinleştiren AIX'i yarışmadan sonra en az 5 yıl boyunca reddetti, tek parçacığın tamamen daha iyi olduğunu savundu. Sybase aynı argümanlardan bazılarını kullandı. Bazı ekiplerin sonunda ortaya çıkmasının tek nedeni, tek iş parçacığı performansının artık CPU düzeyinde makul bir şekilde iyileştirilememesiydi. MP / MT'ye gitmeye ya da giderek daha rekabetçi olmayan bir ürüne sahip olmayı kabul etmeye zorlandılar.

Aktif eşzamanlılık ZORDUR. Ve aldatıcı. Herkes bu kadar kötü olmayacağını düşünerek ona koşar. Sonra bataklığa çarptılar ve ilerlemek zorunda kaldılar. Bunun en az bir düzine isim markası, iyi finanse edilmiş akıllı ekiplerle olduğunu gördüm. Genel olarak, MP / MT ürünleriyle "olması gerektiği yere geri dönüp performans açısından" çok iş parçacığını seçtikten sonra en az beş yıl sürüyordu; çoğu, vardiya yapıldıktan on yıl sonra bile MP / MT verimliliğini / ölçeklenebilirliğini hala anlamlı şekilde geliştiriyordu.

Benim spekülasyonum, GvR'nin onaylanması ve desteklenmemesi durumunda, hiç kimsenin Python ve GIL'in uzun yolunu almamış olması. Bugün bunu yapsalar bile, "Vay canına! MT kamburluğunun üstündeyiz!" Demeden önce Python 4.x zaman dilimi olurdu.

Belki de Python ve çalışma zamanını diğer tüm durumsal altyapı yazılımlarından ayıran bir sihir vardır - daha önce gitmiş olan tüm dil çalışma zamanları, işletim sistemleri, işlem monitörleri ve veritabanı yöneticileri. Ama eğer öyleyse, benzersiz veya neredeyse öyle. Bir GIL eşdeğerini kaldıran herkes, MT'den MT'ye değil, beş yıldan fazla zor, kararlı çaba ve yatırım aldı.


2
+1 Tcl'nin oldukça küçük bir geliştirici ekibiyle çok iş parçacıklı olması zaman aldı. Kod bundan önce MT güvenliydi, ancak çoğunlukla bellek yönetiminde (dinamik diller için çok sıcak bir alan olduğundan şüpheleniyorum) kötü performans sorunları vardı. Deneyim gerçekten Python'a en genel terimlerden başka bir şeyle aktarılmaz; iki dilin tamamen farklı diş açma modelleri vardır. Sadece ... bir slog bekliyoruz ve garip böcek bekliyoruz ...
Donal Fellows

-1

Başka bir vahşi hipotez: 1999'da Linux ve diğer Unices, şimdi olduğu gibi futex(2)( http://en.wikipedia.org/wiki/Futex ) olduğu gibi performanslı bir senkronizasyona sahip değildi . Bunlar 2002 civarında geldi (ve 2004'te 2.6 ile birleştirildi).

Tüm yerleşik veri yapılarının senkronize edilmesi gerektiğinden kilitleme maliyeti çok fazladır. Ӎσᶎ zaten atomik işlemlerin ucuza gerek olmadığını belirtti.


1
Bunu destekleyecek bir şeyin var mı? yoksa bu neredeyse spekülasyon mu?

1
GvR alıntısı, performansı "en hızlı kilitleme ilkeli olan platformda (o sırada Windows)" açıklar, bu nedenle Linux'ta yavaş kilitler önemli değildir.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.