OVH Cloud OVH Cloud

Debian possède ENFIN un noyau entièrement libre...

104 réponses
Avatar
P4nd1-P4nd4
Ca mérite tout de même d'être souligné...

http://digitizor.com/2010/12/16/debian-6-0-squeeze-to-come-with-a-completely-free-linux-kernel/

10 réponses

Avatar
talon
remy wrote:
Tonton Th a écrit :
> On 01/06/2011 02:51 PM, Pascal Hambourg wrote:
>
>>> Partager la mémoire entre des
>>> process différents par contre, c'est peut-être possible (?)
>>
>> Oui c'est possible, et c'est de cela que je parle.
>
> Bon, et un peu de troll : ayant deux classes de "fil" : la
> permière ayant besoin d'accès véloce en r/w à cette mémoire
> partagée, et la seconde n'ayant besoin que d'un d'accès r
> sans nécessité de performance, quelle est la meilleure
> façon de procéder ? shm, mmap, autre ?
>

class MachinBidule:

def init(self):
global val1
self.mutex=QTCore.QMutex()


def write(self,val):
self.mutx.lock()
self.val1=val
self.mutex.unlok()

def read(self):
print(val1)


en gros et non testé

remy





En gros il n'y a pas de sémaphore dans ce programme. Plus en détails
il s'agit de python et en python les mutex n'ont rien à voir avec les
mutex des threads posix. Un mutex de pthread doit être manipulé par le
même thread qui l'a créé, un mutex python peut être libéré par un autre
thread que celui qui l'a bloqué. La raison est qu'en fait un mutex
python est fabriqué à partir d'une variable de condition pthread.
Pour avoir le même genre de comportement en C il faut utiliser mutex
plus variable de condition. Avec le même matériel plus un compteur on
fabrique trivialement un sémaphore commun à plusieurs threads (pas
plusieurs processus, bien sûr).

De toute façon ce n'est pas la question. La question porte sur les
performances. Il paraît que sous Linux le coût de commutation de threads
ou de processus n'est pas très différent, donc je suppute qu'il n'y a
pas de différence de performance significative à utiliser plusieurs
processus synchronisés par des sémaphores ou un processus multithreadé.
Celà étant il y a des coûts de "TLB flushing" qui peuvent être
importants, Idem pour ce qui concerne la constitution de mémoire
partagée via mmap(). Ca me paraît clair que l'usage d'un seul processus
multithreadé est la solution la plus simple et la plus performante.

--

Michel TALON
Avatar
Nicolas George
Michel Talon, dans le message <ig804e$2a9j$,
a écrit :
Il paraît que sous Linux le coût de commutation de threads
ou de processus n'est pas très différent, donc je suppute qu'il n'y a
pas de différence de performance significative à utiliser plusieurs
processus synchronisés par des sémaphores ou un processus multithreadé.



Attention, un sémaphore correspond souvent à un appel système (sous Linux,
les sémaphores SysV font systématiquement un appel système), alors qu'un
mutex se contente en général de code userland atomique.
Avatar
talon
Nicolas George <nicolas$ wrote:
Michel Talon, dans le message <ig804e$2a9j$,
a écrit :
> Il paraît que sous Linux le coût de commutation de threads
> ou de processus n'est pas très différent, donc je suppute qu'il n'y a
> pas de différence de performance significative à utiliser plusieurs
> processus synchronisés par des sémaphores ou un processus multithreadé.

Attention, un sémaphore correspond souvent à un appel système (sous Linux,
les sémaphores SysV font systématiquement un appel système), alors qu'un
mutex se contente en général de code userland atomique.



Il me semble que si un processus ou un thread bloque sur un verrou, et
qu'un autre processus ou thread soit être activé, le noyau intervient
nécessairement (sauf avec du threading N:M) donc le gain éventuel n'est
que dans le cas du verrou non bloquant, ce qui est bien peu probable avec
beaucoup de threads, apparemment. Une variable de condition sert
justement à signaler des choses entre plusieurs threads, donc je suppose
que le noyau doit intervenir. Enfin, je ne sais pas trop, j'ai trouvé
ici, de la bouche du cheval, une discussion de ces questions:
www.kernel.org/doc/ols/2002/ols2002-pages-479-495.pdf

Si chaque thread effectue une tâche substantielle, par exemple un calcul
important sur 2 Gig de données, je doute que les coûts de verrouillage
quels qu'ils soient, aient grande importance. Tous ces microbenchmarks
visant à mettre ces coûts en évidence, portent sur des calculs
minuscules avec un très grand nombre d'acquisition de verrous, le cas
évidemment défavorable. Typiquement si chaque thread doit calculer
quelques dixièmes de secondes ou plus alors que la machine commute
les threads 1000 fois par seconde, ça ne doit pas peser lourd. Si chaque
calcul indépendant prend une microseconde, au contraire les coûts de
verrouillage deviennent prohibitifs. Il me semble que c'est ce qui fait
que les options de parallélisation automatique des compilateurs ont
rarement un résultat favorable, ils font des parallélisations beaucoup
trop "microlocales". Pourtant j'au vu autrefois le compilateur Sun
avec parallélisation automatique produire des résultats spectaculaires.


--

Michel TALON
Avatar
Nicolas George
Michel Talon, dans le message <ig86b9$2c6o$,
a écrit :
Il me semble que si un processus ou un thread bloque sur un verrou, et
qu'un autre processus ou thread soit être activé, le noyau intervient
nécessairement (sauf avec du threading N:M) donc le gain éventuel n'est



Oui.

que dans le cas du verrou non bloquant, ce qui est bien peu probable avec
beaucoup de threads, apparemment.



Si les mutex sont souvent bloquants, c'est qu'ils ne sont pas assez fins.
Avatar
remy
On 7 jan, 19:24, Tonton Th wrote:
On 01/06/2011 05:43 PM, remy wrote:



> en gros et non test

    Et elle est o , la m moire partag e ?

--
Ma coiffeuse est formidable -http://sonia.buvette.org/



import threading
import time
import random
from PyQt4 import QtGui,QtCore


class TasMemoire (QtCore.QThread):

def init(self):
global a
self.a=0
QtCore.QThread.__init__(self,parent=None)
self.mutex=QtCore.QMutex()

def getMemoire(self):
return self.a
def setMemoire(self,val):
self.a=val

def lock(self):
self.mutex.lock()
def unlock(self):
self.mutex.unlock()


class MyThread1 (threading.Thread):
def __init__ (self,mem):
global tas
tas=mem
threading.Thread.__init__ (self, target=self.run)




def run (self):
while True:
r = random.randint(1,5)
print 'thread plus sleep %d '% r
time.sleep(r)
tas.lock()
var=tas.getMemoire()
var=var+1
tas.setMemoire(var)
print 'val= %d'%tas.getMemoire()
tas.unlock()

class MyThread2 (threading.Thread):
def __init__ (self,mem):
global tas
tas=mem
threading.Thread.__init__ (self, target=self.run)




def run (self):
while True:
r = random.randint(1,5)
print 'thread moins sleep %d '% r
time.sleep(r)
tas.lock()
var=tas.getMemoire()
var=var-1
tas.setMemoire(var)
print 'val= %d'%tas.getMemoire()
tas.unlock()



memoire = TasMemoire ()
memoire.init()
Thread1 = MyThread1 (memoire)
Thread1.start()
Thread2 = MyThread2 (memoire)
Thread2.start()


la voila et l'on parle bien de mémoire partagée pas de synchronisation
des threads
et en prime si la moyenne n'est pas égale a zero le random du python a
un problème

remy


remy
Avatar
remy
http://qt-quarterly.developpez.com/qq-11/mutex-lecture-ecriture/

en gros et en détail

remy
Avatar
remy
import threading
import time
import random
from PyQt4 import QtGui,QtCore


class TasMemoire (QtCore.QThread):

def init(self):
global a
self.a=0
self.lecture=0
QtCore.QThread.__init__(self,parent=None)
self.mutex=QtCore.QMutex()

def getMemoire(self):
return self.a
def setMemoire(self,val):
self.a=val
def debutLecture(self):
self.mutex.lock()
self.lecture=self.lecture+1
self.mutex.unlock()

def finLecture(self):
self.lecture=self.lecture-1

def ecriture(self):
self.mutex.lock()
while (self.lecture!=0):
time.sleep(0.1)
def finecriture(self):
self.mutex.unlock()


class add (threading.Thread):
def __init__ (self,mem):
global tas
tas=mem
threading.Thread.__init__ (self, target=self.run)




def run (self):
while True:
r = random.randint(1,5)
time.sleep(r)
tas.ecriture()
var=tas.getMemoire()
var=var+1
tas.setMemoire(var)
tas.finecriture()
tas.debutLecture()
print 'ecriture plus val= %d'%tas.getMemoire()
tas.finLecture()

class sup (threading.Thread):
def __init__ (self,mem):
global tas
tas=mem
threading.Thread.__init__ (self, target=self.run)




def run (self):
while True:
tas.ecriture()
var=tas.getMemoire()
var=var-1
tas.setMemoire(var)
tas.finecriture()
tas.debutLecture()
print 'ecriture moins val= %d'%tas.getMemoire()
tas.finLecture()
r = random.randint(1,5)
time.sleep(r)



class Lecture (threading.Thread):
def __init__ (self,mem):
global tas
tas=mem
threading.Thread.__init__ (self, target=self.run)




def run (self):
while True:

tas.debutLecture()
print 'lecture val= %d'%tas.getMemoire()
tas.finLecture()
r = random.randint(1,5)
time.sleep(r)





memoire = TasMemoire ()
memoire.init()
Thread1 = add (memoire)
Thread1.start()
Thread2 = add (memoire)
Thread2.start()
Thread3 = sup (memoire)
Thread3.start()
Thread4 = sup (memoire)
Thread4.start()

a = Lecture (memoire)
a.start()
b = Lecture (memoire)
b.start()
c = Lecture (memoire)
c.start()
d = Lecture (memoire)
d.start()
e = Lecture (memoire)
e.start()
f = Lecture (memoire)
f.start()
g = Lecture (memoire)
g.start()
h = Lecture (memoire)
h.start()

le même mais dans les règles de l'art c'est mieux

remy
Avatar
talon
remy wrote:
import threading
import time
import random
from PyQt4 import QtGui,QtCore



<snip> 130 lignes de blabla pour faire trois fois rien, et je ne parle
pas de l'utilisation de la librairie Qt pour utiliser les threads de
cette librairie, puis de la librairie threading de python qui utilise
les threads "natifs" de python, comment se passe l'interaction (?), tout
celà pour synchroniser plusieurs threads et non pas plusieurs processus
comme le fait un sémaphore. Cerise sur le gateau, une utilisation
complètement inutile de programmation objet, comme le dit Dijkstra:

"Object-oriented programming is an exceptionally bad idea which could
only have originated in California. "

Tant que le système produira des résultats de cet acabit, je ne donne
pas cher de l'informatique en France.

Des exemples on en trouve autant qu'on veut sur activestate
http://code.activestate.com/recipes/

Pour le threading il y en a 8 pages.
Un example intéressant utilisant uniquementle module thread:
http://code.activestate.com/recipes/475152-thread-syncronizer/

Un exemple concret inspiré de cet exemple, qui montre le bénéfice obtenu
ou non via les threads (attention, python possède un verrou global,
donc en principe du code python ne s'exécute pas de façon concurrente,
exception faite des IO, etc., cependant plusieurs threads impliquent
plus d'occupation du scheduler). Jouer avec le verrouillage dans ce
genre de programmes est un bon moyen d'expérimenter la notion de
deadlock!


#!/usr/bin/env python

import time, thread, math

ntot = 20
nwork = 3

t_start = time.time()


class Wsync :
"Workers synchronize. Collects threads stuff in a clean place."

def __init__(self) :
"Attributes needed by our synchronization procedure."

self.njobs = 0
self.nthr = nwork
self.token = 0
self.dowork = True
self.order = 0
self.nwork = nwork # Number of worker threads

self.eng_l = thread.allocate_lock() # To control token engine loop
self.tok_l = thread.allocate_lock() # To protect njobs and token
self.exit_l = thread.allocate_lock() # To protect nthr at the end

self.eng_l.acquire() # Must be initialized to locked

def work(self, order) :

while self.dowork :
self.tok_l.acquire()
# One should have njobs > 0 here, since threads are
# launched after tokens
if self.njobs > 0 :
orig = self.token
self.njobs -= 1
if self.eng_l.locked() : # Restarts the token engine
self.eng_l.release()
self.tok_l.release()
run_hard_work(orig, order) # Do real work
else : # njobs = 0 strange!
self.tok_l.release()
time.sleep(0.001) # Yields to another thread
# Cleanup at the end
self.tok_l.acquire()
if self.njobs > 0 : # Eventually picks last job
orig = self.token
self.njobs -= 1
self.tok_l.release()
run_hard_work(orig, order)
else :
self.tok_l.release()

self.exit_l.acquire() # Signals end of thread
self.nthr -= 1
self.exit_l.release()

def finish(self) :
"Main thread waits for end of all worker threads."

get_out = False
while not get_out :
self.exit_l.acquire()
if self.nthr > 0 :
self.exit_l.release()
else :
get_out = True # Exits
self.exit_l.release()


# The engine, launches tokens, and start worker threads.

def engine(self, orig) :
"Distributes tokens, here parameter orig."

self.tok_l.acquire()
self.token = orig
self.njobs += 1
self.tok_l.release()
if self.order < self.nwork : # Launch nwork threads
thread.start_new_thread(self.work, (self.order,))
self.order += 1
self.eng_l.acquire() # Blocks engine until token acquired


###### a test work program #########################

def run_hard_work(ori, order) :
"Simulates work."

for jjj in range(200000) :
res = math.sin(jjj * ori / 10000)
print "unit", order, "token", ori, "result", res # Prints last result only

###### run the threaded computation ################

worker = Wsync() # Creates a Wsync instance, initially worker.dowork = True

for origin in range(ntot) :
worker.engine(origin) # Emits threads for i < nwork and tokens

worker.dowork = False # Signals end of work to threads

worker.finish() # Waits that all threads finish

###### end of the threaded computation #############

thr_time = time.time() - t_start
print "Exiting. Took", thr_time, "to run."
print "And now serial computation."

t_start = time.time()

for ora in range(ntot) :
for jjk in range(200000): # Simulate work
resu = math.sin(ora * jjk / 10000)
print "token", ora, "result", resu

ser_time = time.time() - t_start

print "Exiting. Took", ser_time, "to run."
print "Threading bonus is", 100*(ser_time -thr_time)/thr_time, "%"





--

Michel TALON
Avatar
remy
Michel Talon a écrit :
remy wrote:
import threading
import time
import random
from PyQt4 import QtGui,QtCore



<snip> 130 lignes de blabla pour faire trois fois rien, et je ne parle
pas de l'utilisation de la librairie Qt pour utiliser les threads de
cette librairie, puis de la librairie threading de python qui utilise
les threads "natifs" de python, comment se passe l'interaction (?), tou t
celà pour synchroniser plusieurs threads et non pas plusieurs process us
comme le fait un sémaphore. Cerise sur le gateau, une utilisation
complètement inutile de programmation objet, comme le dit Dijkstra:

"Object-oriented programming is an exceptionally bad idea which could
only have originated in California. "

Tant que le système produira des résultats de cet acabit, je ne don ne
pas cher de l'informatique en France.




connerie si si
l'obj est une abstraction tout comme les langages, python ,c ,java ,lisp
,etc
un truc pour facilite la vie du programmeur un interface homme /machine
ou code assembleur , micro code
un mutex ou un sémaphore c'est la même chose, l'un est fait pour les
threads et l'autre (les sémaphores) c'est pour les processus leur
finalité est la même
partager une ressource ou faire une syncro la différence réside dans la
sémantique et l'environnement dans lequel ils sont utilisés







Des exemples on en trouve autant qu'on veut sur activestate
http://code.activestate.com/recipes/




c'est de la syncro a la portée du premier couillon qui passe tu léve un
lock et tu attends
de tout manier je peut te faire la même chose en c , java pour les
thread, ou basic avec une double liste et un boolean
et l'algo sera le même si si ,la différence résidera dans la puissa nce
des obj ou des fonctions utilisées

ces agencements doivent dater de début de l'aire informatique en gros
plus de 40 à 50 ans

après la différence réside dans la transposition et le compilateur

remy


--
http://remyaumeunier.chez-alice.fr/
Avatar
JKB
Le Mon, 10 Jan 2011 09:54:33 +0100,
remy écrivait :
Michel Talon a écrit :
remy wrote:
import threading
import time
import random
from PyQt4 import QtGui,QtCore



<snip> 130 lignes de blabla pour faire trois fois rien, et je ne parle
pas de l'utilisation de la librairie Qt pour utiliser les threads de
cette librairie, puis de la librairie threading de python qui utilise
les threads "natifs" de python, comment se passe l'interaction (?), tout
celà pour synchroniser plusieurs threads et non pas plusieurs processus
comme le fait un sémaphore. Cerise sur le gateau, une utilisation
complètement inutile de programmation objet, comme le dit Dijkstra:

"Object-oriented programming is an exceptionally bad idea which could
only have originated in California. "

Tant que le système produira des résultats de cet acabit, je ne donne
pas cher de l'informatique en France.




connerie si si
l'obj est une abstraction tout comme les langages, python ,c ,java ,lisp
,etc
un truc pour facilite la vie du programmeur un interface homme /machine
ou code assembleur , micro code



Non, l'objet est un truc pour former rapidement des générations de
programmeurs médiocres. Lorsque tu codes en C ou en C++ fonctionnel
(ou en Fortran voire en Cobol ou dans d'autres langages
fonctionnels), tu dois avoir une idée de ce que tu veux faire et une
certaine rigueur. L'utilisation des objet ajoute juste une couche
d'abstraction inutile. Cela consomme des ressources pour rien. Quant
à la généricité des objets, je me marre en entendant ça parce que
c'est particulièrement inefficace. Regarde Boost de près et recode
les fonctions de Boost en fonction d'un problème particulier et tu
verras la différence d'efficacité. Personnellement, je l'ai fait
avec la boost/graph en C pur. le résultat est supérieur à mes
espoirs les plus fous.

un mutex ou un sémaphore c'est la même chose,



NON ! Un mutex, c'est un point d'arrêt pour régler les accès
concurrents. Un sémaphore, c'est une décrémentation et un test
atomique sur une variable. Cela _peut_ servir de mutex sur des zones
de mémoire partagée (encore qu'on puisse utiliser un mutex dans la
même variable partagée sous certaines conditions), mais cela sert
aussi à un tas d'autres choses.

l'un est fait pour les
threads et l'autre (les sémaphores) c'est pour les processus leur
finalité est la même
partager une ressource ou faire une syncro la différence réside dans la
sémantique et l'environnement dans lequel ils sont utilisés



Mon dieu... N'utilise que des mots que tu comprends.

Des exemples on en trouve autant qu'on veut sur activestate
http://code.activestate.com/recipes/




c'est de la syncro a la portée du premier couillon qui passe tu léve un
lock et tu attends
de tout manier je peut te faire la même chose en c , java pour les
thread, ou basic avec une double liste et un boolean
et l'algo sera le même si si ,la différence résidera dans la puissance
des obj ou des fonctions utilisées



Il te manque le mot _atomique_. Enfin, avec ton booléen, tupeux
essayer. Ça fonctionnera dans 99% des cas et pour le 1% qui restera,
ça explorsera en vol et tu chercheras longtemps la source du
problème.

ces agencements doivent dater de début de l'aire informatique en gros
plus de 40 à 50 ans



?

après la différence réside dans la transposition et le compilateur



Le compilo, il ne fait que ce que tu lui demandes de faire. Si tu
oublies le côté atomique, tu risques fort d'avoir des problèmes quel
que soit le compilo et le langage.

JKB

--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr