<?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>Ornthalas.net &#187; Résultats de recherche  &#187;  expression</title>
	<atom:link href="http://www.ornthalas.net/search/expression/feed/rss2/" rel="self" type="application/rss+xml" />
	<link>http://www.ornthalas.net</link>
	<description>Coin.</description>
	<lastBuildDate>Mon, 06 Sep 2010 11:49:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Bistromathique</title>
		<link>http://www.ornthalas.net/2009/10/23/bistromathique/</link>
		<comments>http://www.ornthalas.net/2009/10/23/bistromathique/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 09:28:17 +0000</pubDate>
		<dc:creator>Ornthalas</dc:creator>
				<category><![CDATA[Informatique]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[bistromathique]]></category>
		<category><![CDATA[calculatrice]]></category>
		<category><![CDATA[Epita]]></category>
		<category><![CDATA[epitech]]></category>
		<category><![CDATA[projet]]></category>

		<guid isPermaLink="false">http://www.ornthalas.net/?p=48</guid>
		<description><![CDATA[J&#8217;avais fait un bel article sur mon ancien blog, avec toutes les idées que j&#8217;avais eues à la fin du projet d&#8217;Ing1 : Bistromathique. Comme plusieurs personnes m&#8217;ont demandé des infos sur le projet, je vais refaire cet article ici à partir des bribes trouvées dans la base de données que j&#8217;ai gardée. Nous avons [...]]]></description>
			<content:encoded><![CDATA[<p>J&#8217;avais fait un bel article sur mon ancien blog, avec toutes les idées que j&#8217;avais eues à la fin du projet d&#8217;Ing1 : Bistromathique. Comme plusieurs personnes m&#8217;ont demandé des infos sur le projet, je vais refaire cet article ici à partir des bribes trouvées dans la base de données que j&#8217;ai gardée.</p>
<blockquote><p>Nous avons planché sur plusieurs projets en langage C depuis le début de l&#8217;année, mais un seul a réellement retenu mon attention : il s&#8217;agit de la Bistromathique. Qu&#8217;est ce que cela ? Il s&#8217;agit d&#8217;une calculatrice capable de travailler sur des grandes bases (ici on a implémenté jusqu&#8217;à la base 249) et sur des nombres entiers signés potentiellement infinis (nous nous sommes limités à une expression ayant pour taille maximale 4 294 967 295 caractères).</p>
<p>J&#8217;ai commencé par travailler sur une représentation en tableaux de caractères (tableaux d&#8217;entiers 8 bits non signés : des unsigned char* sur archi 32 bits), en implémentant l&#8217;addition, la soustraction et la multiplication scolaire, ainsi qu&#8217;un algorithme proche de celui de Knuth pour la division et le modulo. J&#8217;ai utilisé les tableaux en Big Endian pour faciliter les opérations commençant sur les poids faibles, et pour éliminer rapidement les 0 non-significatifs. De plus, le décalage à gauche étant plus souvent utilisé que le décalage à droite, cette représentation de chiffres était doublement intéressante.</p>
<p>Ma première grosse optimisation a été de récupérer les buffers déjà alloués pour les stocker dans une chaine de buffers vides. Mine de rien, j&#8217;ai multiplié par au moins 50 la vitesse de ma bistro avec cette astuce ! En effet, j&#8217;allouais pour chaque opérande de mon expression, ce qui faisait des milliers de mallocs ! Grâce à cette technique, sans même me casser la tête à trier les buffers vides dans la liste chainée, je suis descendu entre 10 et 25 mallocs sur tout le programme ! (Mes tests étaient composés d&#8217;expressions de 10 Mo et d&#8217;opérandes de 1 ko à 10 ko.)</p>
<p>J&#8217;ai ensuite transformé le programme pour qu&#8217;il utilise des tableaux d&#8217;entiers 32 bits non signés (unsigned long* ou unsigned int* sur archi 32 bits) et j&#8217;ai adapté l&#8217;addition et la soustraction. Voyant que les résultats étaient plus lents sur ceux-ci, j&#8217;ai abandonné cette voie de recherche (mauvaise pioche, j&#8217;aurais du continuer) : en effet, cette implémentation nécessite 3 parcours linéaires pour les additions et soustractions, mais accélère considérablement les multiplications !</p>
<p>Ensuite, pour accélérer ma multiplication, j&#8217;ai travaillé sur l&#8217;algorithme de Karatsuba. Malgré mes efforts sur la gestion mémoire, je n&#8217;ai pas pu empêcher l&#8217;allocation de deux structures de nombres et des chaines de caractères les accompagnant à chaque récursion de l&#8217;algorithme, ce qui a multiplié par 12 le nombre d&#8217;appels systèmes de mon programme sur mes tests. La conséquence de cela a été qu&#8217;en utilisant Karatsuba plutôt que la multiplication naïve, je doublais le temps de calcul.</p>
<p>Pressé par le temps, je me suis rabattu sur une optimisation de la multiplication naïve en utilisant seulement pour elle la représentation en tableaux d&#8217;unsigned long. Le gros point faible est qu&#8217;à chaque multiplication, je fais trois conversions : deux pour passer les deux opérandes en unsigned long*, et une pour repasser le résultat en unsigned char*. Malgré cela, mes résultats sur la multiplication naïve on été fulgurants (division par 9 à 18 du temps de calcul)</p>
<p>J&#8217;ai ensuite été contraint à rendre mon travail, timeout projet oblige.</p>
<p>Mes idées restantes si j&#8217;avais encore eu du temps :</p>
<ul>
<li>Repasser entièrement sur des tableaux d&#8217;unsigned long, tellement plus rapides pour les opérations complexes (multiplication, division et modulo).</li>
<li>Retravailler Karatsuba notamment en allouant sur la pile plutôt que sur le tas à l&#8217;aide des tableaux dynamiques apportés par le C99 auquel nous avions droit</li>
<li>Trouver une astuce pour calculer rapidement l&#8217;heuristique de mon algorithme de Knuth modifié avec la nouvelle représentation des nombres.</li>
<li>Pouvoir gérer l&#8217;expression originale comme un buffer utilisable, donc pour cela déterminer les parties d&#8217;expression traitées pour utiliser cet espace mémoire obsolète : celui-ci était alloué à 10 Mo minimum, ca aurait été un gain considérable !</li>
<li>Permettre deux représentations de nombres en parallèle avec conversion éventuelle selon le type d&#8217;opération à effectuer pour accélérer les calculs type addition/soustraction seulement lorsque les opérandes viennent de l&#8217;expression originale)</li>
</ul>
<p>Au final, je peux dire que ce projet m&#8217;a énormément appris, tant sur la gestion mémoire que sur de nouveaux algos (parseur LL d&#8217;expression mathématique, Karatsuba, Knuth&#8230;) ou sur l&#8217;expérience du debug (maintenant je ne peux plus travailler en C sans Valgrind tellement c&#8217;est utile).</p>
<p><em><span style="text-decoration: underline;">Note</span> </em>: Je ne peux pas donner mon code source ici, simplement parce que d&#8217;autres épitéens ont des chances de tomber sur cette page alors qu&#8217;ils ont le projet à coder. Si certaines personnes veulent voir mon travail, qu&#8217;elles me contactent.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.ornthalas.net/2009/10/23/bistromathique/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
