Derniers journaux de iug :
- [08/11@16:38] Validation des distributions GNU/Linux
- [19/04@11:09] Comment débugger l'allocation mémoire en Ocaml ?
- [13/04@09:48] Mldonkey stable
- [03/03@11:01] L'allocation mémoire et les langages fonctionnels
- [23/02@10:58] Encore des dépendances de modules, Linux c'est crad :)
- [23/02@10:14] Une petite question sur le chargement des modules
- [20/02@10:57] Mandrake 10 ?
- [27/01@23:19] Ils ont tout compris
- [27/01@23:19] Ils ont tout compris
- [23/12@21:25] Pourquoi ?
- [15/12@10:45] Droits d'auteur et Numérique
- [28/11@11:39] Le plugin Java et la Mandrake 9.2
- [24/11@12:30] Freebox en USB sous Linux
- [04/11@10:44] Moteur de recherche
- [04/11@10:42] Les moteurs de recherche
- [24/09@13:54] Le net rame ?!?
- [15/08@12:02] Problème de disque dur
- [19/06@09:53] SUN SU><OR
- [19/06@09:52] Sun SU><OR
- [27/05@08:33] Les Opterons en France
Journal : La terre est plate et Java est plus rapide que C++
Posté par iug () le 15 avril 2005Je vous propose un petit troll du Vendredi, ainsi qu'un défi.
J'utilise Java Sound pour enregistrer et jouer du son. J'avais, avec le JDK 1.3 des problèmes de pertes de synchro, i.e. Java arrivait pas à suivre la cadence. Les marketteux de chez Sun prétendant que Java Sound était maintenant en Direct Sound (pas celui de M$, celui de Java) depuis la 1.4, utilisant Alsa ou bien DirectX, marchait beaucoup mieux.
Le problème c'est que Java, c'est peut-être plus rapide que C++, mais ça ne sait pas scheduler un thread correctement.
En effet, ma carte son me donne un buffer d'enregistrement de 1s au max (avec Direct Sound on ne peut pas choisir la taille du buffer, et maintenant Sun ne donne plus accès au Java Audio Engine pour l'enregistrement). Du coup, il faut que mon thread d'enregistrement soit schédulé au moins une fois par seconde.
Et ben cette merde de Scheduler qu'il y'a dans la JDK, il est pas capable de me faire ça. A peu près toutes les 30s, mon thread n'est pas schédulé à temps. Pourtant je lui demande un scheduling toutes les 100ms via un wait(100) dans mon thread. Et ce, sans que rien ne tourne en tâche de fond, sauf les processus de mon OS et les quelques threads "system" de la JVM.
Sur un Pentium IV 2.4GHz avec 1 Go de RAM, 0% d'utilisation CPU, le scheduler de la JVM n'est pas foutu de faire en sorte que mon thread soit schedulé avant 1s.
Du coup, le son en Java on peut oublier :)
Je vais coder un bout de C++ pour gérer ça et passer par JNI.
Conclusion la terre est plate (c.f. la page performance sur jsresources.org).
> Lire le journal (42 commentaires, moyenne: 2,3).
Je prends les paris
Tu ne crains pas que la conclusion du débat soit qu'en fait c'est ton truc qui est mal codé ?
-
[^]Re: Je prends les paris
Posté par iug () le 15/04/2005 à 09:50. (lien). Évalué à 6.J'ai oublié la partie "défi" qui consistait à me proposer un code qui démontre mon incompétence.
-
[^]Re: Je prends les paris
Posté par gc (page perso, ) le 15/04/2005 à 13:27. (lien). Évalué à 5.Et pourquoi tu ne montres pas ton code tout simplement pour que d'autres y jettent un coup d'oeil et voient quelque chose que peut-être tu n'as pas vu ?
-
[^]Re: Je prends les paris
Posté par iug () le 15/04/2005 à 14:03. (lien). Évalué à 1.Désolé, je bosse dans le privé, j'ai pas le droit. Essaie même pas d'imaginer sur quel OS tourne mon code :)
-
[^]Re: Je prends les paris
Posté par Nelis (page perso, ) le 15/04/2005 à 14:07. (lien). Évalué à 2.Tu peux peut être nous montrer uniquement la partie posant problème ? J'imagine qu'elle n'est pas si secrete que ça ... Sinon comment veux-tu qu'on t'aide ? Si ça se trouve, il y a un bug dans ton code que tu n'as pas trouvé ...
Sinon c'est comme si je disais : le C sous Linux c'est pas bien parce que mon thread se désynchronise, alors que j'ai surement un gros bug dans mon code ...--
Vache qui rit, à moitié dans son lit-
[^]Re: Je prends les paris
Posté par iug () le 15/04/2005 à 15:38. (lien). Évalué à 2.Bon, voilà mon code :
_in est une TargetDataLine en Java Direct Sound,
_bigBuf, c'est un plus gros buffer circulaire dans lequel je mets mes données, et que le player va lire pour les jouer sur la carte son par exemple (on va supposer qu'il marche...) (même quand seul le recorder est seul, sans player, j'ai le problème, bon ok, j'ai pas essayé sans la copie vers le bigBuf)
le corps du run() est :
while (started) {
size = _in.available(); // récupère la taille des données dispo
_in.read(buf, 0, size); // récupère les données (une copie //supplémentaire, je sais)
_bigBuf.put(buf, 0, size); // écrit dans le buffer circulaire
Thread.wait(100); // Attends au moins 100ms, si possible moins de 1s
}
Ca ne vous avance pas à grand chose. Sinon, y'a des sorties textes de debug au milieu de tout ça, ce qui peut expliquer la chose. M'enfin, je suis plus au taf, donc je peux pas essayer.
Merci pour la proposition, mais ça vous avance à rien. Y'a pas de deadlock vu que seul un consommateur tourne :) Si mon buffer circulaire buggait, j'aurais des excpetions. Vu qu'il ne fait pas 1Mo ça n'explique de toute façon pas la latence, une copie de 1Mo prenant moins d'une seconde. Une copie de plus de 1Mo déclencherais une excpetion...-
[^]Pfff
Posté par bobert () le 15/04/2005 à 16:26. (lien). Évalué à 0.Ca ne vous avance pas à grand chose
En fait, ça n'avance même à rien, vu que tu donnes un code incomplet.
Quel est le type de _in ? InputStream ? BufferedInputStream ?
Quel est le type de buf ? Où est le code de _bigBuf ? Que fait sa méthode put ?
Évidemment en nous montrant 3 lignes tronquées de ton code ça fait pas du tout avancer le schmilblik, à croire que tu fais exprès, ça doit faire partie de ton troll.
Tout ce que ça montre, c'est que tu es plus habitué à c++ qu'à java, parce que préfixer d'un '_' le nom des attributs privés est un idiome c++ ; en java, on se contente du modifiant private.-
[+] [^]Re: Pfff
Posté par Troy McClure (page perso, ) le 15/04/2005 à 17:57. (lien). Évalué à -3.> préfixer d'un '_' le nom des attributs privés est un idiome c++
Naon, en c++ comme en c, les identifieurs commençant par un underscore sont reservés pour l'usage interne du compilo et de la bibliothèque standard !
-
[^]Re: Pfff
Posté par Matthieu Moy (page perso, ) le 16/04/2005 à 11:48. (lien). Évalué à 3.> Quel est le type de _in ?
Bien relire le message du môsieur ...-
[^]Re: Pfff
Posté par iug () le 18/04/2005 à 10:34. (lien). Évalué à 2.Mon soft est censé cohabiter avec du hard, qui m'envoie 1s de son toutes les secondes. Donc j'utilise directement une TargetDataLine, et je fait un read dessus.
Et en mettant des currentTimeMillis() partout, j'ai vu que mon appel à _in.read() avec comme dernier paramètre le résultat renvoyé par _in.available(), qui ne devrait donc pas bloquer, prend la plupart de temps à peu près 0 ms et de temps à autre 1000ms, comme si il bloquait pour attendre un remplissage complet du buffer interne de la carte son, qui dur 1000ms.
Le scheduler n'est pas en cause, ni ma synchro, le wait() du thread dure grosso modo ce qu'il faut. D'ailleurs, chose bizarre, il dure parfois moins que le temps demandé.
Je vais essayer de creuser le problème. Par exemple ma carte est une fausse full duplex.-
[^]Re: Pfff
Posté par iug () le 18/04/2005 à 12:46. (lien). Évalué à 5.Ouais, c'était bien une histoire de TargetDataLine.read().
Je sais pas si c'est dû au driver de ma carte son, à DirectX, ou au JDK mais maintenant que je lis 1000 octets de moins que ce que me donne le available() et ben jai plus de read() bloquant.
Toutes mes excuses pour les critiques du scheduler, qui n'était pas en cause, de même que le GC.
-
-
-
-
[^]Re: Je prends les paris
Posté par Sylvain Sauvage () le 17/04/2005 à 19:38. (lien). Évalué à 4.Le Thread.wait(100), comme tu le dis en commentaire, signifie « attends au moins 100 ms ».
C'est tout.
Java n'est pas temps réel (ton OS non plus, je pense), il ne promet pas que le retour se fera avant un délai donné (il peut très bien finir dans 25 ans).
Ton problème vient peut-être des entrées-sorties ou du garbage collector qui viennent perturber l'ordonnanceur.
Ensuite, ce n'est parce que tu vas passer par du JNI que la machine virtuelle ou les entrées-sorties ne vont pas continuer à venir perturber le fonctionnement de ton prog.
Sans parler des problèmes que l'on peut avoir en mélangeant les threads natifs aux threads Java.
Enfin, si tu n'as aucun raison pour faire un Thread.wait(100) plutôt qu'un Thread.wait(10), autant faire un Thread.yield(). De cette façon, ton thread reprendra la main dès que possible.
-
-
-
-
-
[^]Bien tenté...
-
-
[^]Re: Je prends les paris
Posté par iug () le 15/04/2005 à 10:01. (lien). Évalué à 2.Quiconque a déjà écrit un prod/cons en Java connaît le problème.
Si tu fais juste un petit programme "cas décole" qui ne fait aucun traitement et se contente de faires des println dans la console à chaque production et consommation, tu observeras des pauses assez fréquentes.
Ce qui me fait halluciner c'est que ces pauses peuvent durer plus d'une seconde.
Je me demande si ce sontles programmeurs qui ont implémentés le truc qui sont incompétents ou bien, pire, si c'est une faille de la spec d'implémentation des API de thread qu'ils ont en interne chez Sun.
Quand on voit la qualité de Solaris, on se dit qu'ils pourraient débaucher quelques hackers pour les mettre à bosser sur Java.-
[^]Re: Je prends les paris
Posté par Nelis (page perso, ) le 15/04/2005 à 10:10. (lien). Évalué à 3.Je n'ai jamais eu de problème de synchro de threads en Java ...
Peut-être peux-tu nous montrer ton code ?--
Vache qui rit, à moitié dans son lit
-
[^]Re: Je prends les paris
Posté par Mathieu CLAUDEL (page perso, ) le 15/04/2005 à 10:11. (lien). Évalué à 5.<neophite>
peut etre le garbage colector qui tourne
</neophite>
-
[^]Re: Je prends les paris
Posté par Laurent Pointal (page perso, ) le 15/04/2005 à 11:08. (lien). Évalué à 1.Voir le Java 1.5, il y a des options pour affiner le fonctionnement du ramasse-miettes, de mémoire on peut spécifier qu'on veut qu'il s'active obligatoirement tous les XXX secondes, et on peut spécifier qu'à chaque activation il ne doit pas prendre plus de YYY secondes.
(y'avait un article là-dessus dans un numéro de GNU-Linux Magazine)-
[^]Re: Je prends les paris
Posté par Tobu () le 15/04/2005 à 17:59. (lien). Évalué à 1.Et il y a certainement des options pour demander au GC de loguer quand il se met à travailler. Avec un top, il y a certainement moyen de voir si le système part au swap (je suppose que tu as un top, même si c'est un système exotique?) (de toute façon si ça supporte java ça peut pas être une petite plateforme).
-
[^]Re: Je prends les paris
Posté par Krunch (Jabber id, page perso, ) le 15/04/2005 à 21:18. (lien). Évalué à 2.Un GSM c'est pas une petite plateforme ?
--
Free Softwares Users Group Arlon (Sud Luxembourg, Belgique)
pertinent, e adj. Approprié ; qui se rapporte exactement à ce dont il est question.-
[^]Re: Je prends les paris
-
[^]Re: Je prends les paris
Posté par gc (page perso, ) le 16/04/2005 à 19:57. (lien). Évalué à 2.T'as déjà regardé les features de J2ME par rapport à celles de J2SE ?
Je te suggère aussi de lire ce qui suit :
http://www.armadilloaerospace.com/n.x/johnc/recent%20updates/archiv(...)
-
-
-
-
-
[^]Re: Je prends les paris
Posté par Thomas Hervé () le 15/04/2005 à 10:15. (lien). Évalué à 4.Un petit test qui résoud certains problèmes : augmente la taille initiale de la ram alouée à la JVM (-Xms128m pour mettre 128MB par exemple).
Au cours de tests d'applis Web sous Tomcat, j'ai utilisé un outil pas mal qui s'appelle Jprobe profiler (ca pue c'est pas libre). Pour constater que les latences de mon application étaient dues aux allocations mémoire. En gros quand la JVM augmente (ou diminue) la mémoire disponible, elle ne peut rien faire d'autre ou quasiment... Sachant qu'une application Java est assez consommatrice de mémoire, j'avais des pauses toutes les 10 secondes.
--
Thomas <et voilà que je me met à donner des conseils Java. Tout fout le camp>-
[^]Re: Je prends les paris
Posté par kesako () le 15/04/2005 à 10:27. (lien). Évalué à 3.ah ben alors c'est vraiment lamentable ... car un exemple de producteur/consomateur ca ne devrait pas faire grossir l'occupation memoire. Ca peut eventuellement grossir au debut mais ensuite doit se stabiliser . Donc les "pauses" n'ont aucune raison d'etre.
-
[^]Re: Je prends les paris
-
[^]Re: Je prends les paris
Posté par Laurent Pointal (page perso, ) le 15/04/2005 à 11:06. (lien). Évalué à 3.Si, ça fait grossir jusqu'au prochain passage du ramasse-miettes.
-
-
[^]Re: Je prends les paris
-
-
[^]Re: Je prends les paris
Posté par romain () le 15/04/2005 à 10:19. (lien). Évalué à 3.Est-ce que ça ne viendrait pas aussi du choix du modèle de threading de la JVM ?
Il me semble, si je me souviens bien mes cours de temps réel (en Java, vivi), qu'il y a au moins deux modèles (green box, native ou standard, je ne sais plus) et que cela peut avoir une incidence sur le scheduling des threads et leurs synchro (pas de pointeur en tête, désolé).-
[^]Re: Je prends les paris
Posté par iug () le 15/04/2005 à 10:41. (lien). Évalué à 1.Ca c'est intéressant comme réponse, je songeais justement à lire les howto de IBM sur le paramètrage de la JVM.
En tout cas, question RT, effectivement Java ne donne pas plus de garantie que Linux vanilla ou Windows en matière de schéduling. Par contre dans ces deux derniers cas, dans la pratique, on n'a pas de latence de 1s.
Question pause, et ben oui elles y sont. Et effectivement, je me suis démerder pour ne plus faire d'alloc dans ma boucle de pompage, et les pauses y sont encore.-
[^]Re: Je prends les paris
Posté par Mobaladje () le 15/04/2005 à 11:09. (lien). Évalué à 2.J'avoue je ne comprends pas bien ton probleme.
"A peu près toutes les 30s, mon thread n'est pas schédulé à temps."
Ca veut dire quoi exactement ?
Le wait ne se fait pas ? (très improbable).
Les waits n'étant pas "constants", tu as une attente plus longue (ou plus courte) au bout d'un certain temps ? (plus probable).
Que veux tu faire exactement ?-
[^]Re: Je prends les paris
Posté par Tobu () le 15/04/2005 à 17:53. (lien). Évalué à 2.Son tampon a une taille de 1 seconde, et son thread reste apparemment au moins 1 seconde sans s'exécuter, ce qui fait que le tampon se retrouve vide.
D'ou bizarrerie: le thread n'est censé ne dormir que 100ms.-
[^]Re: Je prends les paris
Posté par jigso () le 16/04/2005 à 11:55. (lien). Évalué à 3.C'est donc que le pb n'est pas dans le wait(100), mais probable dans les opérations de lecture/copie de buffer ; dans la mesure où il ne fait pas du temps réels, ie pas d'appel de fonctions qui peuvent garantir un temps d'execution minimum, tout peut arriver, y compris des "gels" de plus d'1 seconde - probablement le ramasse-miette ou autre joyeuseté de la JVM.
-
-
-
-
-
[^]Re: Je prends les paris
Posté par Nicolas Bernard (page perso, ) le 15/04/2005 à 11:48. (lien). Évalué à 0.
Quand on voit la qualité de Solaris, on se dit qu'ils pourraient débaucher quelques hackers pour les mettre à bosser sur Java.
Je crois que les hackers en question préfereraient démissioner que de travailler sur Java...
-
[+] J'ai pas constaté.
Je fais pas du temps réel, mais j'utilise des applications java diverses, jedit, Eclipse...
Je ne constate pas des pauses d'une seconde périodiques.
Ton problème n'est probablement pas généralisé à tout java. Reste a trouver ce qui le déclenche.
-
[^]Re: J'ai pas constaté.
Posté par TImaniac (page perso, ) le 15/04/2005 à 14:20. (lien). Évalué à 0.j'utilise des applications java diverses, jedit, Eclipse...
Non sérieux, c'est bien connu, Eclipse il ralenti jamais, surtout quand le GC passe dans le coin, y'a jamais plus de 2 µs entre le click de la souris et la réaction de l'IHM, c'est bien connu, surtout au bout de 3h d'utilisation, sous Linux s'il vous plaît...
Bon allez j'ai assez ri, hop -->[]
vu sur le site de SUN
je sais pas si cela peux t'aider, mais bon :
exemple de thread schedulé :
http://forum.java.sun.com/thread.jspa?forumID=45&threadID=24306(...)
Help with JMF Synchronisation :
http://forum.java.sun.com/thread.jspa?forumID=28&threadID=52346(...)
tutorial:
http://java.sun.com/docs/books/tutorial/essential/threads/priority.(...)
doc :
Capturing Time-Based Media with JMF :
http://java.sun.com/products/java-media/jmf/2.1.1/guide/JMFCapturin(...)
javasound
franchement javaSound c'est une très grosse merde au niveau performances (et encore je pèse mes mots..). La seule solution que j'ai trouvé et JNI & libasound (alsa) qui marche plutôt bien mais qui n'est pas portable pour Windows
-
[^]Re: javasound
Posté par iug () le 15/04/2005 à 12:45. (lien). Évalué à 5.J'ai l'impression que le dernier JavaSound, qui utilise alsa en accès direct est pas mal. Le seul problème c'est leur scheduler et leur GC.
-
[+] [^]Re: javasound
Posté par vrm (page perso, ) le 15/04/2005 à 13:09. (lien). Évalué à -1.j'ais pas essayé le dernier tellement les précédents étaient mauvais ...
-
une "solution"
plus un contournement qu'autre chose : t'as essaye de remplacer ton thread par un Timer?
ca correspond plus a ce que tu veux faire visiblement (ie : executer une tache toutes les n ms plutot que d'executer une tache en continue qui dort 90% du temps)
-
[^]Re: une "solution"
[+] \o/
> Le problème c'est que Java, c'est peut-être plus rapide que C++
c'est une blague j'espere :)
[+] Lâcher de trolls
Je vous propose un petit troll du Vendredi, ainsi qu'un défi.
J'utilise Java Sound pour enregistrer et jouer du son. J'avais, avec le JDK 1.3 des problèmes de pertes de synchro, i.e. Java arrivait pas à suivre la cadence.
Tu te prends pour Pierre Tramo ?
Les journaux sont destinés à des informations qui ne sont pas suffisamment intéressantes
pour être validées en dépêche (sinon n'hésitez pas à proposer votre information en
dépêche), qui sont sans rapport avec Linux ou le libre, ou simplement pour donner votre
avis. Si vous désirez poser une question, merci d'utiliser 

Cette discussion est archivée, il n'est plus possible de laisser des commentaires.
Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.