<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Thibaut Cuvelier &#187; Compilateurs</title>
	<atom:link href="https://blog.developpez.com/dourouc05/pcategory/compilateurs/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/dourouc05</link>
	<description></description>
	<lastBuildDate>Tue, 27 Dec 2016 09:30:53 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>LLVM lance un nouveau projet : parallel-lib</title>
		<link>https://blog.developpez.com/dourouc05/p13053/hpc/llvm-lance-un-nouveau-projet-parallel-lib</link>
		<comments>https://blog.developpez.com/dourouc05/p13053/hpc/llvm-lance-un-nouveau-projet-parallel-lib#comments</comments>
		<pubDate>Sun, 19 Jun 2016 13:02:04 +0000</pubDate>
		<dc:creator><![CDATA[dourouc05]]></dc:creator>
				<category><![CDATA[Compilateurs]]></category>
		<category><![CDATA[HPC et calcul scientifique]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/dourouc05/?p=1592</guid>
		<description><![CDATA[Il y a trois mois, Google proposait son projet StreamExecutor à LLVM. Cette bibliothèque sert à lancer des calculs sur des processeurs graphiques et d&#8217;autres types d&#8217;accélérateurs, principalement pour leur solution d&#8217;apprentissage profond TensorFlow. L&#8217;avantage est de disposer d&#8217;un système &#8230; <a href="https://blog.developpez.com/dourouc05/p13053/hpc/llvm-lance-un-nouveau-projet-parallel-lib">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://blog.developpez.com/dourouc05/p13017/hpc/google-envisage-de-contribuer-son-streamexecutor-dans-llvm">Il y a trois mois, Google proposait son projet StreamExecutor à LLVM</a>. Cette bibliothèque sert à lancer des calculs sur des processeurs graphiques et d&rsquo;autres types d&rsquo;accélérateurs, principalement pour leur solution d&rsquo;apprentissage profond <a href="http://www.developpez.com/actu/92381/Google-rend-open-source-TensorFlow-son-tout-nouveau-systeme-de-machine-learning/">TensorFlow</a>. L&rsquo;avantage est de disposer d&rsquo;un système unique pour lancer des calculs sur ce type d&rsquo;accélérateur, sans dépendre de la bibliothèque qui sera effectivement utilisée pour les calculs. Cette couche d&rsquo;abstraction ne fait &laquo;&nbsp;que&nbsp;&raquo; gérer l&rsquo;évolution des calculs sur les accélérateurs selon le concept de flux (emprunté à NVIDIA CUDA), d&rsquo;où le nom de la bibliothèque. Ce projet StreamExecutor s&rsquo;inscrit notamment dans la lignée d&rsquo;OpenMP 4, avec la possibilité de décharger une partie du code sur des accélérateurs à l&rsquo;aide d&rsquo;une directive spécifique (offload). </p>
<p>Suite à cette proposition de code de la part de Google, <a href="http://lists.llvm.org/pipermail/llvm-dev/2016-March/096576.html">après quelques mois de discussions, lancées par la proposition de Google</a>, LLVM lance un nouveau sous-projet orienté programmation concurrente : parallel-libs. Ce projet est présenté comme un parallèle concurrent à compiler-rt, qui rassemble diverses fonctionnalités (implémentation générique d&rsquo;instructions non disponibles sur certains processeurs, assainisseurs de code, etc.). </p>
<p>En quelques mots, les objectifs de parallel-libs sont plus étendus que ceux de StreamExecutor : ce sous-projet pourra contenir des moteurs d&rsquo;exécution comme celui d&rsquo;OpenMP, des bibliothèques d&rsquo;accès au matériel à l&rsquo;instar de StreamExecutor, voire des fonctions mathématiques implémentées en parallèle. La seule contrainte pour une inclusion dans parallel-libs est d&rsquo;être à la croisée des chemins des compilateurs et de l&rsquo;exécution concurrente, ce qui permettra de partager du code. </p>
<p>Pour le moment, les décisions sont prises, mais le projet n&rsquo;a pas encore d&rsquo;existence physique (pas d&rsquo;emplacement sur le dépôt SVN de LLVM, pas de liste de diffusion). Cela ne devrait pas tarder. D&rsquo;ailleurs, IBM pourrait rejoindre la danse, avec <a href="http://lists.llvm.org/pipermail/cfe-dev/2016-February/047547.html">leurs projets d&rsquo;interface unique pour lancer du code, que ce soit avec CUDA ou OpenMP</a>, pour lesquels <a href="https://github.com/llvm-mirror/clang/commit/def8b33bd90fe6b8a47636d41e96875bb1c2ac79">un premier commit est arrivé</a>. </p>
<p>Source : <a href="http://lists.llvm.org/pipermail/llvm-dev/2016-June/101028.html">[llvm-dev] parallel-lib: New LLVM Suproject</a>. </p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Un nouvel optimiseur de code pour Visual C++</title>
		<link>https://blog.developpez.com/dourouc05/p13037/langages/cpp/un-nouvel-optimiseur-de-code-pour-visual-c</link>
		<comments>https://blog.developpez.com/dourouc05/p13037/langages/cpp/un-nouvel-optimiseur-de-code-pour-visual-c#comments</comments>
		<pubDate>Sat, 07 May 2016 13:45:20 +0000</pubDate>
		<dc:creator><![CDATA[dourouc05]]></dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Compilateurs]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/dourouc05/?p=1418</guid>
		<description><![CDATA[Les compilateurs sont des programmes informatiques d&#8217;une importante complexité. Ils sont généralement structurés en une partie frontale, qui comprend le langage d&#8217;entrée, puis d&#8217;une partie arrière, qui s&#8217;occupe de traduire le programme d&#8217;entrée en du code binaire exécutable par le &#8230; <a href="https://blog.developpez.com/dourouc05/p13037/langages/cpp/un-nouvel-optimiseur-de-code-pour-visual-c">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Les compilateurs sont des programmes informatiques d&rsquo;une importante complexité. Ils sont généralement structurés en une partie frontale, qui comprend le langage d&rsquo;entrée, puis d&rsquo;une partie arrière, qui s&rsquo;occupe de traduire le programme d&rsquo;entrée en du code binaire exécutable par le processeur. Les deux parties communiquent à l&rsquo;aide d&rsquo;une représentation intermédiaire (IR). Ainsi, pour qu&rsquo;une même suite de compilateurs comprenne plusieurs langages et puisse générer du code pour plusieurs processeurs, il n&rsquo;est pas nécessaire d&rsquo;écrire un compilateur spécifique pour chaque paire langage-processeur : il suffit d&rsquo;écrire les paires langage-IR et IR-processeur. Tout le travail effectué pour un processeur sera alors utilisable pour n&rsquo;importe quel langage d&rsquo;entrée. </p>
<p><img src="http://tcuvelier.developpez.com/news/images/cpp/visual-cpp-ssa/structuregenerale.svg" /></p>
<p>Dès la génération du code intermédiaire, un compilateur utilise énormément de passes d&rsquo;optimisation, afin de rendre le code plus rapide. Elle utilise des techniques comme la propagation des valeurs : si une variable a une valeur connue à un endroit du code (initialisation, condition…), alors cette valeur peut être propagée dans une série de calculs, qui seront alors effectués à la compilation au lieu de l&rsquo;exécution. Ces passes sont effectuées en partie sur la représentation intermédiaire, pour les optimisations indépendantes du processeur, mais également sur du code machine déjà généré, pour tirer le meilleur parti possible du matériel. </p>
<p>Généralement, cette phase d&rsquo;optimisation est extrêmement cruciale, étant donné que la représentation intermédiaire est suffisamment générale pour plusieurs types de processeurs et relativement simple dans les instructions disponibles : pour effectuer certaines opérations, il est parfois nécessaire d&rsquo;écrire des dizaines d&rsquo;instructions IR, alors que certains processeurs peuvent réaliser la même opération en une seule instruction. De plus, une représentation intermédiaire doit être prête pour les phases d&rsquo;optimisation qui suivent, notamment en simplifiant toutes les étapes de raisonnement : dans les IR de type SSA, notamment, une variable ne peut être assignée qu&rsquo;une seule fois, ce qui allonge d&rsquo;autant plus le code. </p>
<p><strong>Un nouvel optimiseur pour Visual C++</strong></p>
<p>Le compilateur C++ de Microsoft, connu sous le nom de Visual C++, a longtemps été laissé dans un état proche de l&rsquo;abandon. Depuis quelques années, les équipes de développement ont mis les bouchées doubles pour ramener le compilateur dans la course, avec une compatibilité avec les normes les plus récentes, au niveau de GCC ou Clang. Depuis lors, ils ont effectivement rattrapé en grande partie leur retard à ce niveau, mais pas encore pour les optimisations du code. </p>
<p>L&rsquo;optimiseur actuel ne disposait que d&rsquo;une série de transformations assez basiques, n&rsquo;exploitant qu&rsquo;une vue assez limitée des fonctions. Bon nombre d&rsquo;optimisations fonctionnent en trouvant des motifs et en les remplaçant par une version améliorée, mais tous les motifs les plus utiles ne sont pas toujours implémentés. De plus, le code vectorisable n&rsquo;est pas optimisé au meilleur de ses possibilités. Toutes ces limitations ont une origine historique : le compilateur C++ de Microsoft a des origines très anciennes, il provient de l&rsquo;époque DOS où la mémoire était très limitée, ce qui limite les possibilités. Les efforts actuels portent principalement sur une modernisation du code, en éliminant les compromis d&rsquo;un autre âge. </p>
<p>Le nouvel optimiseur exploite désormais une représentation intermédiaire SSA. Les algorithmes implémentés par-dessus peuvent ainsi être plus efficaces en temps par rapport aux approches par analyse du flux de données. Il se base sur une bibliothèque C++ avancée, exploitant les <em>templates</em> à foison, pour décrire les transformations à effectuer, ce qui a permis d&rsquo;ajouter bon nombre d&rsquo;optimisations simples en très peu de temps (surtout par rapport à l&rsquo;infrastructure précédente). </p>
<p>Les développeurs de Visual C++ indiquent également avoir prêté attention à la correction de ces optimisations : il n&rsquo;y a rien de plus désagréable que de passer des journées à déboguer son code pour trouver que, finalement, le problème n&rsquo;est pas dû au code, mais bien au compilateur. <a href="http://lkml.iu.edu//hypermail/linux/kernel/1407.3/00650.html">Linus Torvalds a récemment torpillé GCC à ce sujet</a>. Ici, les développeurs ont absolument cherché à éviter ces écueils, en testant leurs passes d&rsquo;optimisation sur des programmes courants comme Chrome ou Firefox, puis sur des bibliothèques imposantes côté Microsoft comme CoreCLR ou Chakra. </p>
<p>Ils ont aussi employé des techniques de vérification formelle (<a href="https://github.com/nunoplopes/alive">à l&rsquo;aide d&rsquo;ALIVE</a> et <a href="https://github.com/Z3Prover/z3">l&rsquo;outil de démonstration automatique Z3</a>, tous deux issus de Microsoft Research et <a href="http://web.stanford.edu/~mlfbrown/fp.pdf">aussi utilisés pour LLVM</a>) et de la génération de code aléatoire avec <a href="https://embed.cs.utah.edu/csmith/">Csmith</a> (et <a href="https://embed.cs.utah.edu/creduce/">C-Reduce pour réduire le code posant problème au strict minimum</a>). Certains outils du projet LLVM ont pu être utilisés, <a href="http://www.developpez.com/actu/91544/Microsoft-va-integrer-le-compilateur-Clang-dans-une-mise-a-jour-de-Visual-Cplusplus-qui-est-attendue-en-novembre-2015/">puisque Visual C++ peut en exploiter les parties avant</a>, comme <a href="https://github.com/regehr/opt-fuzz">Opt-fuzz, qui génère des expressions arithmétiques à optimiser</a>. </p>
<p><strong>Un exemple</strong></p>
<p>Ces nouvelles optimisations peuvent avoir un effet assez radical sur certains bouts de code. Par exemple, pour un test de parité :</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">int</span> test<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> a<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> a <span style="color: #000040;">%</span> <span style="color: #0000dd;">2</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span> <span style="color: #008080;">?</span> <span style="color: #0000dd;">4</span> <span style="color: #008080;">:</span> <span style="color: #0000dd;">2</span><span style="color: #008080;">;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p>Les précédentes versions du compilateur produisaient un code qui prenait entre cinq et dix cycles en x86, selon que tout le processeur est exploité (prédiction du branchement parfaite) ou non :</p>
<div class="codecolorer-container asm default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="asm codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">?<span style="color: #00007f; font-weight: bold;">test</span>@@YAHH@Z <span style="color: #000000; font-weight: bold;">PROC</span><br />
&nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">and</span> &nbsp; <span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">2147483647</span><br />
&nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">jge</span> &nbsp; <span style="color: #000000; font-weight: bold;">SHORT</span> $LN3@<span style="color: #00007f; font-weight: bold;">test</span><br />
&nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">dec</span> &nbsp; <span style="color: #00007f;">ecx</span><br />
&nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">or</span> &nbsp; &nbsp;<span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">2</span><br />
&nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">inc</span> &nbsp; <span style="color: #00007f;">ecx</span><br />
$LN3@<span style="color: #00007f; font-weight: bold;">test</span><span style="color: #339933;">:</span><br />
&nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">test</span> &nbsp;<span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ecx</span><br />
&nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">mov</span> &nbsp; <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">2</span><br />
&nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">mov</span> &nbsp; <span style="color: #00007f;">edx</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">4</span><br />
&nbsp; &nbsp; cmovne <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #00007f;">edx</span><br />
&nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">ret</span> &nbsp; <span style="color: #0000ff;">0</span></div></div>
<p>Sauf que… Dans le test <code class="codecolorer cpp default"><span class="cpp">a <span style="color: #000040;">%</span> <span style="color: #0000dd;">2</span> <span style="color: #000080;">==</span> <span style="color: #0000dd;">0</span></span></code>, le signe de <code class="codecolorer cpp default"><span class="cpp">a</span></code> n&rsquo;a aucune espèce d&rsquo;importance, seul un bit est important : le modulo peut être remplacé par une opération logique, c&rsquo;est-à-dire <code class="codecolorer cpp default"><span class="cpp">a <span style="color: #000040;">&amp;</span> <span style="color: #0000dd;">1</span> <span style="color: #000080;">==</span> <span style="color: #0000dd;">0</span></span></code>. Or, la comparaison implique un branchement dans le code, forcément lent sur les architectures x86 modernes : pour s&rsquo;en débarrasser, la structure <code class="codecolorer cpp default"><span class="cpp"><span style="color: #0000ff;">bool</span><span style="color: #008000;">&#40;</span>a<span style="color: #008000;">&#41;</span> <span style="color: #008080;">?</span> C1 <span style="color: #008080;">:</span> C2</span></code> peut être remplacée par <code class="codecolorer cpp default"><span class="cpp">C2 <span style="color: #000040;">+</span> a<span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span>C1<span style="color: #000040;">-</span>C2<span style="color: #008000;">&#41;</span></span></code>, c&rsquo;est-à-dire exclusivement des calculs. Par conséquent, le nouveau code assembleur est le suivant :</p>
<div class="codecolorer-container asm default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="asm codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">?<span style="color: #00007f; font-weight: bold;">test</span>@@YAHH@Z <span style="color: #000000; font-weight: bold;">PROC</span><br />
&nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">and</span> &nbsp; <span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">1</span><br />
&nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">lea</span> &nbsp; <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">DWORD</span> <span style="color: #000000; font-weight: bold;">PTR</span> <span style="color: #009900; font-weight: bold;">&#91;</span>rcx<span style="color: #339933;">*</span><span style="color: #0000ff;">2</span><span style="color: #339933;">+</span><span style="color: #0000ff;">2</span><span style="color: #009900; font-weight: bold;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">ret</span> &nbsp; <span style="color: #0000ff;">0</span></div></div>
<p>Celui-ci prend, à tous les coups, deux cycles d&rsquo;horloge : par rapport à cinq à dix cycles, le gain est important, tant en rapidité qu&rsquo;en taille de l&rsquo;exécutable. </p>
<p>D&rsquo;autres mécanismes effectuent une analyse statique du code, en précalculant autant de bits que possible dans les variables. Par exemple, lors d&rsquo;une conversion vers un type plus grand, une série de bits est forcément à zéro, peu importe la valeur d&rsquo;entrée. Ensuite, cette information peut être adaptée en fonction des opérations effectuées, ce qui peut guider le reste du processus.</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000ff;">int</span> test<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">char</span> a<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">short</span> b <span style="color: #000080;">=</span> a<span style="color: #008080;">;</span> &nbsp; &nbsp;<span style="color: #666666;">// b: 00000000________, a: ________ </span><br />
&nbsp; &nbsp; b <span style="color: #000080;">&lt;&lt;=</span> <span style="color: #0000dd;">4</span><span style="color: #008080;">;</span> &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666;">// b: 0000________0000 </span><br />
&nbsp; &nbsp; b <span style="color: #000040;">|</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">3</span><span style="color: #008080;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">// b: 0000________0011</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">return</span> b <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> &nbsp;<span style="color: #666666;">// -&gt; return true &nbsp; </span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p><strong>Impact sur la taille du code généré</strong></p>
<p>L&rsquo;impact de ces modifications sur le code généré n&rsquo;est pas facile à établir : certaines optimisations diminuent forcément la quantité de code, le compilateur sera alors plus enclin à recopier <em>in extenso</em> le code de petites fonctions pour éviter le surcoût dû à tout appel de fonction (qui n&rsquo;est négligeable que pour des fonctions plus grandes) — ce qui conduit à l&rsquo;augmentation de la taille du code. Il n&rsquo;empêche, les résultats sont intéressants : sur tout Windows, c&rsquo;est-à-dire plus d&rsquo;un gigaoctet, les gains sont de 438 Ko par rapport à l&rsquo;optimiseur précédent (0,3 %) ; sur SQL Server, 46 Ko sur 64 Mo (0,8 %) ; sur Chakra, le nouveau moteur JavaScript, 10 Ko sur 6 Mo (1,7 %). </p>
<p>En analysant plus en détail l&rsquo;impact au niveau des instructions, les plus lentes sont largement évitées (branchements, multiplications, divisions), remplacées par des opérations plus rapides (comme des déplacements conditionnels). Les temps de compilation ont été impacté de diverses manières : une augmentation de 1,7 % pour Chrome ou une diminution de 2,6 % pour le noyau Windows. </p>
<p><strong>Et alors ?</strong></p>
<p>Les travaux sur l&rsquo;optimiseur viennent seulement d&rsquo;être annoncés : l&rsquo;architecture choisie permettra aux développeurs d&rsquo;ajouter des optimisations supplémentaires rapidement (et certaines sont déjà en cours de planification). Cet optimiseur devrait arriver dès Visual C++ 2015 Update 3, mais le travail continuera sur cet aspect du compilateur, afin de le rendre compétitif par rapport à ses concurrents, voire de les dépasser. <a href="https://blogs.msdn.microsoft.com/vcblog/2016/02/16/try-out-the-latest-c-compiler-toolset-without-waiting-for-the-next-update-of-visual-studio/">Il est d&rsquo;ores et déjà possible de le tester</a>. </p>
<p>Source : <a href="https://blogs.msdn.microsoft.com/vcblog/2016/05/04/new-code-optimizer/">Introducing a new, advanced Visual C++ code optimizer</a>.<br />
L&rsquo;image a été créée par l&rsquo;auteur et est soumise au droit d&rsquo;auteur. </p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
