<?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>گنجه &#187; بهینه‌سازی</title>
	<atom:link href="http://blog.ebrahim.ir/tag/optimization/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ebrahim.ir</link>
	<description># tail -f /var/log/experience</description>
	<lastBuildDate>Wed, 25 Aug 2010 22:16:39 +0000</lastBuildDate>
	<language>fa</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>روشی برای تسریع dpkg</title>
		<link>http://blog.ebrahim.ir/1388/07/a-technique-for-speeding-up-dpkg/</link>
		<comments>http://blog.ebrahim.ir/1388/07/a-technique-for-speeding-up-dpkg/#comments</comments>
		<pubDate>Fri, 09 Oct 2009 00:56:15 +0000</pubDate>
		<dc:creator>ابراهیم</dc:creator>
				<category><![CDATA[رایانه]]></category>
		<category><![CDATA[APT]]></category>
		<category><![CDATA[BASH]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[dpkg]]></category>
		<category><![CDATA[Ext4]]></category>
		<category><![CDATA[ReiserFS]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Tokyo Cabinet]]></category>
		<category><![CDATA[بهینه‌سازی]]></category>
		<category><![CDATA[سامانهٔ عامل]]></category>
		<category><![CDATA[سامانهٔ پرونده]]></category>
		<category><![CDATA[لوح سخت]]></category>
		<category><![CDATA[لینوکس]]></category>
		<category><![CDATA[محک‌زنی]]></category>
		<category><![CDATA[کارآیی]]></category>

		<guid isPermaLink="false">http://blog.ebrahim.ir/?p=292</guid>
		<description><![CDATA[همون طور که احتمالاً می‌دونید dpkg توساخت0 مدیریت بسته‌ها1 در Debian است. یعنی APT و Synaptic و Aptitude و &#8230; همه روی dpkg بنا شده اند. dpkg برای نگه‌داری بعضی اطلاعات بسته‌های نصب‌شده، از تعداد زیادی (برای من حدود ۹۰۰۰ تا) پروندهٔ2 کوچک توی مسیر ‎/var/lib/dpkg/info استفاده می‌کنه. هر بار که بسته‌ای رو نصب یا [...]]]></description>
			<content:encoded><![CDATA[<p><!--startnum=0--></p>
<p>همون طور که احتمالاً می‌دونید dpkg توساخت<sup><a href="http://blog.ebrahim.ir/1388/07/a-technique-for-speeding-up-dpkg/#footnote_0_292" id="identifier_0_292" class="footnote-link footnote-identifier-link" title="Back-end">0</a></sup> مدیریت بسته‌ها<sup><a href="http://blog.ebrahim.ir/1388/07/a-technique-for-speeding-up-dpkg/#footnote_1_292" id="identifier_1_292" class="footnote-link footnote-identifier-link" title="Package management">1</a></sup> در Debian است. یعنی APT و Synaptic و Aptitude و &#8230; همه روی dpkg بنا شده اند.</p>
<p>dpkg برای نگه‌داری بعضی اطلاعات بسته‌های نصب‌شده، از تعداد زیادی (برای من حدود ۹۰۰۰ تا) پروندهٔ<sup><a href="http://blog.ebrahim.ir/1388/07/a-technique-for-speeding-up-dpkg/#footnote_2_292" id="identifier_2_292" class="footnote-link footnote-identifier-link" title="File">2</a></sup> کوچک توی مسیر ‎/var/lib/dpkg/info استفاده می‌کنه. هر بار که بسته‌ای رو نصب یا حذف می‌کنید dpkg همهٔ اون پرونده‌ها رو از روی لوح<sup><a href="http://blog.ebrahim.ir/1388/07/a-technique-for-speeding-up-dpkg/#footnote_3_292" id="identifier_3_292" class="footnote-link footnote-identifier-link" title="Disk">3</a></sup> می‌خونه. این کار روی سامانهٔ پروندهٔ<sup><a href="http://blog.ebrahim.ir/1388/07/a-technique-for-speeding-up-dpkg/#footnote_4_292" id="identifier_4_292" class="footnote-link footnote-identifier-link" title="File system">4</a></sup> مورد استفادهٔ من، که Ext4 هست، اولین بار بیست-سی ثانیه‌ای طول می‌کشه، که برای من مدت زیادی هست. این کار در دفعات بعدی به علت قرار گرفتن همهٔ اون پرونده‌ها در نهان‌گاه<sup><a href="http://blog.ebrahim.ir/1388/07/a-technique-for-speeding-up-dpkg/#footnote_5_292" id="identifier_5_292" class="footnote-link footnote-identifier-link" title="Cache">5</a></sup> سامانهٔ پرونده در حافظهٔ اصلی، بسیار سریع‌تر انجام می‌شه، تا وقتی که دوباره از نهان‌گاه خارج بشند.</p>
<p>این مشکل هر از گاهی یک سیخی بهم می‌زد و روی اعصابم راه می‌رفت. فکرهای مختلفی برای حلش به ذهنم رسید. از بسیار پیچیده، مثل طراحی و پیاده‌سازی مجدد dpkg روی Tokyo Cabinet یا SQLite، تا بسیار ساده:</p>
<p>شاید بدونید که سامانهٔ پروندهٔ ReiserFS در کار با پرونده‌های کوچک بسیار عالی عمل می‌کنه. علتش هم استفاده از فن «ته‌چِپانی»<sup><a href="http://blog.ebrahim.ir/1388/07/a-technique-for-speeding-up-dpkg/#footnote_6_292" id="identifier_6_292" class="footnote-link footnote-identifier-link" title="Tail packing">6</a></sup> است.<sup><a href="http://blog.ebrahim.ir/1388/07/a-technique-for-speeding-up-dpkg/#footnote_7_292" id="identifier_7_292" class="footnote-link footnote-identifier-link" title="http://en.wikipedia.org/wiki/ReiserFS#Performance">7</a></sup> فکر کردم شاید اگر پوشهٔ  ‎/var/lib/dpkg/info رو توی ReiserFS نگه دارم، مشکل حل بشه. این کار رو کردم، ولی به خاطر کارکرد<sup><a href="http://blog.ebrahim.ir/1388/07/a-technique-for-speeding-up-dpkg/#footnote_8_292" id="identifier_8_292" class="footnote-link footnote-identifier-link" title="Mechanism">8</a></sup> داخلی dpkg روی کل ‎/var/lib/dpkg:</p>

<div class="wp_syntax" dir="ltr"><div class="code"><pre class="none" style="font-family:monospace;">$ sudo su -
# cd /var/lib
# tar cpzf dpkg.tar.gz dpkg
# dd if=/dev/zero of=dpkg.reiserfs bs=$((256*1024*1024)) count=1
# mkreiserfs -f dpkg.reiserfs
# mount -oloop dpkg.reiserfs dpkg
# tar xpf dpkg.tar.gz</pre></div></div>

<p>و بعد آزمودن و دائمی کردن با افزودن به fstab‏:</p>

<div class="wp_syntax" dir="ltr"><div class="code"><pre class="none" style="font-family:monospace;"># echo 3 &gt;/proc/sys/vm/drop_caches
# apt-get install hello
# apt-get purge hello
# echo /var/lib/dpkg.reiserfs /var/lib/dpkg reiserfs loop,noatime 0 1 &gt;&gt;/etc/fstab</pre></div></div>

<p>فکره جواب داد و سرعت dpkg بسیار به‌تر شد. حالا حتی اولین بار هم dpkg اون کار رو در دو-سه ثانیه انجام می‌ده.</p>
<p>علاوه بر مهارت ReiserFS در کار با پرونده‌های کوچک، چند نکتهٔ دیگه هم قابل ذکر هست. یکی این که Ext4 به علت فن «حوزه»<sup><a href="http://blog.ebrahim.ir/1388/07/a-technique-for-speeding-up-dpkg/#footnote_9_292" id="identifier_9_292" class="footnote-link footnote-identifier-link" title="Extent">9</a></sup> در کار با پرونده‌های نسبتاً بزرگی که یک‌جا تخصیص<sup><a href="http://blog.ebrahim.ir/1388/07/a-technique-for-speeding-up-dpkg/#footnote_10_292" id="identifier_10_292" class="footnote-link footnote-identifier-link" title="Allocation">10</a></sup> می‌یابند بسیار سریع هست. برای همین به dd گفتم که کل پرونده رو یک‌جا بسازه.</p>
<p>از طرفی چون، در نتیجهٔ نکتهٔ قبل، کل پرونده‌های مربوط به dpkg روی لوح نزدیک به هم قرار می‌گیرند و پراکنده نیستند، با خونده شدن یک پرونده از اون حوالی، تعداد زیادی از بقیه‌شون هم توی نهان‌گاه لوح و تعدادی هم توی نهان‌گاه سامانهٔ پرونده قرار می‌گیرند. همین امر باعث می‌شه کلی زمان جویش<sup><a href="http://blog.ebrahim.ir/1388/07/a-technique-for-speeding-up-dpkg/#footnote_11_292" id="identifier_11_292" class="footnote-link footnote-identifier-link" title="Seek">11</a></sup> که قبلاً برای رسیدن به پرنده‌های پراکنده در اطراف و اکناف لوح هدر می‌رفت، صرفه‌جویی بشه.</p>
<p>به گزینهٔ<sup><a href="http://blog.ebrahim.ir/1388/07/a-technique-for-speeding-up-dpkg/#footnote_12_292" id="identifier_12_292" class="footnote-link footnote-identifier-link" title="Option">12</a></sup> noatime در fstab هم دقت کنید. رفتار معمولی سامانه‌های پرونده این هست که در هر دست‌رسی (اعم از خواندن یا نوشتن) به یک پرونده، زمان دست‌رسی رو ذخیره می‌کنند. این خیلی بده! هر دست‌رسی = حداقل یک عمل نوشتن روی لوح، و عمل نوشتن هم معمولاً کندتر از خوندن هست. نکته این جاست که برنامه‌های رایج امروزی معمولاً روی اون زمان ثبت‌شده برای آخرین دست‌رسی حساب نمی‌کنند و عملاً اون عدد بی‌استفاده است! گزینهٔ noatime به سامانهٔ پرونده می‌گه که کلاً قید ثبت اون زمان رو بزنه و به این ترتیب کلی عمل نوشتن صرفه‌جویی کنه.</p>
<ol start="0" class="footnotes"><li id="footnote_0_292" class="footnote">Back-end</li><li id="footnote_1_292" class="footnote">Package management</li><li id="footnote_2_292" class="footnote">File</li><li id="footnote_3_292" class="footnote">Disk</li><li id="footnote_4_292" class="footnote">File system</li><li id="footnote_5_292" class="footnote">Cache</li><li id="footnote_6_292" class="footnote">Tail packing</li><li id="footnote_7_292" class="footnote">http://en.wikipedia.org/wiki/ReiserFS#Performance</li><li id="footnote_8_292" class="footnote">Mechanism</li><li id="footnote_9_292" class="footnote">Extent</li><li id="footnote_10_292" class="footnote">Allocation</li><li id="footnote_11_292" class="footnote">Seek</li><li id="footnote_12_292" class="footnote">Option</li></ol>]]></content:encoded>
			<wfw:commentRss>http://blog.ebrahim.ir/1388/07/a-technique-for-speeding-up-dpkg/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>بهینه‌سازی هدایت‌شده با سابقه</title>
		<link>http://blog.ebrahim.ir/1387/12/profile-guided-optimization/</link>
		<comments>http://blog.ebrahim.ir/1387/12/profile-guided-optimization/#comments</comments>
		<pubDate>Tue, 03 Mar 2009 03:57:45 +0000</pubDate>
		<dc:creator>ابراهیم</dc:creator>
				<category><![CDATA[رایانه]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[C++‎]]></category>
		<category><![CDATA[CMake]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[GCC]]></category>
		<category><![CDATA[PGO]]></category>
		<category><![CDATA[ابزار]]></category>
		<category><![CDATA[برنامه‌نویسی]]></category>
		<category><![CDATA[بهینه‌سازی]]></category>
		<category><![CDATA[سابقه‌گیری]]></category>
		<category><![CDATA[لینوکس]]></category>
		<category><![CDATA[هم‌گردان]]></category>
		<category><![CDATA[ویندوز]]></category>
		<category><![CDATA[کارآیی]]></category>

		<guid isPermaLink="false">http://blog.ebrahim.ir/?p=200</guid>
		<description><![CDATA[یکی از روش‌های نسبتاً متفاوت هم‌گردان0ها برای بهینه‌سازی1، روش «بهینه‌سازی هدایت‌شده با سابقه»2 است که گاهی اون رو کوتاهانه3 PGO هم می‌گویند. مؤثر بودن این روش رو می‌شه به چشم دید. مثلاً اگر از مرورگر Firefox هم در لینوکس4 و هم در ویندوز5 استفاده کرده باشید، حتماً تفاوت فاحش کارآیی6 رو حس کرده‌اید. دلیل این [...]]]></description>
			<content:encoded><![CDATA[<p><!--startnum=0--></p>
<p>یکی از روش‌های نسبتاً متفاوت هم‌گردان<sup><a href="http://blog.ebrahim.ir/1387/12/profile-guided-optimization/#footnote_0_200" id="identifier_0_200" class="footnote-link footnote-identifier-link" title="Compiler">0</a></sup>ها برای بهینه‌سازی<sup><a href="http://blog.ebrahim.ir/1387/12/profile-guided-optimization/#footnote_1_200" id="identifier_1_200" class="footnote-link footnote-identifier-link" title="Optimization">1</a></sup>، روش «بهینه‌سازی هدایت‌شده با سابقه»<sup><a href="http://blog.ebrahim.ir/1387/12/profile-guided-optimization/#footnote_2_200" id="identifier_2_200" class="footnote-link footnote-identifier-link" title="Profile-Guided Optimization">2</a></sup> است که گاهی اون رو کوتاهانه<sup><a href="http://blog.ebrahim.ir/1387/12/profile-guided-optimization/#footnote_3_200" id="identifier_3_200" class="footnote-link footnote-identifier-link" title="به یاد استاد روحانی رانکوهی!">3</a></sup> PGO هم می‌گویند.</p>
<p>مؤثر بودن این روش رو می‌شه به چشم دید. مثلاً اگر از مرورگر Firefox هم در لینوکس<sup><a href="http://blog.ebrahim.ir/1387/12/profile-guided-optimization/#footnote_4_200" id="identifier_4_200" class="footnote-link footnote-identifier-link" title="Linux">4</a></sup> و هم در ویندوز<sup><a href="http://blog.ebrahim.ir/1387/12/profile-guided-optimization/#footnote_5_200" id="identifier_5_200" class="footnote-link footnote-identifier-link" title="Windows">5</a></sup> استفاده کرده باشید، حتماً تفاوت فاحش کارآیی<sup><a href="http://blog.ebrahim.ir/1387/12/profile-guided-optimization/#footnote_6_200" id="identifier_6_200" class="footnote-link footnote-identifier-link" title="Performance">6</a></sup> رو حس کرده‌اید. دلیل این تفاوت فاحش، استفاده از PGO در ساخت<sup><a href="http://blog.ebrahim.ir/1387/12/profile-guided-optimization/#footnote_7_200" id="identifier_7_200" class="footnote-link footnote-identifier-link" title="Build">7</a></sup> پروندهٔ<sup><a href="http://blog.ebrahim.ir/1387/12/profile-guided-optimization/#footnote_8_200" id="identifier_8_200" class="footnote-link footnote-identifier-link" title="File">8</a></sup> اجرایی<sup><a href="http://blog.ebrahim.ir/1387/12/profile-guided-optimization/#footnote_9_200" id="identifier_9_200" class="footnote-link footnote-identifier-link" title="Executable">9</a></sup> ویندوز و عدم استفاده ازش در ساخت اجرایی لینوکس بیان شده.</p>
<p>خوب، حالا که به اندازهٔ کافی انگیزوندمتون (!)، ببینیم این روش اصلاً چی هست و چه‌جوری می‌تونیم ازش استفاده کنیم.</p>
<p>اساس این روش، استفاده از اطلاعات کسب‌شده در زمان اجرا<sup><a href="http://blog.ebrahim.ir/1387/12/profile-guided-optimization/#footnote_10_200" id="identifier_10_200" class="footnote-link footnote-identifier-link" title="Run-time">10</a></sup>ی برنامه، برای بهینه‌سازی در زمان هم‌گردانی<sup><a href="http://blog.ebrahim.ir/1387/12/profile-guided-optimization/#footnote_11_200" id="identifier_11_200" class="footnote-link footnote-identifier-link" title="Compile-time">11</a></sup> هست. پس هم‌گردانی با این روش، سه مرحله خواهد داشت:</p>
<p>۱. هم‌گردانی برای تولید اجرایی مخصوص جمع‌آوری اطلاعات مورد نیاز برای بهینه‌سازی<br />
۲. اجرای برنامهٔ تولیدشده در مرحلهٔ ۱ و استفاده از موارد کاربرد<sup><a href="http://blog.ebrahim.ir/1387/12/profile-guided-optimization/#footnote_12_200" id="identifier_12_200" class="footnote-link footnote-identifier-link" title="Use case">12</a></sup> مورد نظر برای بهینه‌سازی<br />
۳. هم‌گردانی با بهینه‌سازی به کمک اطلاعات جمع‌آوری‌شده در مرحلهٔ ۲</p>
<p>هم‌گردان‌ها برای مراحل ۱ و ۳ گزینه‌های مخصوصی دارند که این‌جا فقط GCC رو می‌بینیم.</p>
<p>درGCC برای مرحلهٔ ۱ از گزینهٔ ‎-fprofile-generate و برای مرحلهٔ ۳ از گزینهٔ ‎-fprofile-use استفاده می‌کنیم. دقت کنید که گزینهٔ ‎-fprofile-generate رو هم باید برای هم‌گردانی<sup><a href="http://blog.ebrahim.ir/1387/12/profile-guided-optimization/#footnote_13_200" id="identifier_13_200" class="footnote-link footnote-identifier-link" title="Compiling">13</a></sup> بدید، و هم برای پیوند<sup><a href="http://blog.ebrahim.ir/1387/12/profile-guided-optimization/#footnote_14_200" id="identifier_14_200" class="footnote-link footnote-identifier-link" title="Linking">14</a></sup>.</p>
<p>من که معمولاً از CMake به عنوان سامانهٔ ساخت<sup><a href="http://blog.ebrahim.ir/1387/12/profile-guided-optimization/#footnote_15_200" id="identifier_15_200" class="footnote-link footnote-identifier-link" title="Build System">15</a></sup> استفاده می‌کنم، برای به کارگیری این روش، این چند خط رو به CMakeLists.txt اضافه می‌کنم:</p>

<div class="wp_syntax" dir="ltr"><div class="code"><pre class="none" style="font-family:monospace;"># profile::generate
#set(CMAKE_C_FLAGS &quot;${CMAKE_C_FLAGS} --profile-generate&quot;)
#set(CMAKE_CXX_FLAGS &quot;${CMAKE_CXX_FLAGS} --profile-generate&quot;)
#set(CMAKE_EXE_LINKER_FLAGS &quot;${CMAKE_EXE_LINKER_FLAGS} --profile-generate&quot;)
# profile::use
#set(CMAKE_C_FLAGS &quot;${CMAKE_C_FLAGS} --profile-use&quot;)
#set(CMAKE_CXX_FLAGS &quot;${CMAKE_CXX_FLAGS} --profile-use&quot;)
#set(CMAKE_EXE_LINKER_FLAGS &quot;${CMAKE_EXE_LINKER_FLAGS} --profile-use&quot;)</pre></div></div>

<p>برای مرحلهٔ ۱، سه تا set اول و برای مرحلهٔ ۳، سه تا set دوم رو فعال می‌کنم. راستی دقت کردید که به جای ‎-fprofile-folan می‌شه از  ‎-profile-folan- استفاده کرد؟!</p>
<ol start="0" class="footnotes"><li id="footnote_0_200" class="footnote">Compiler</li><li id="footnote_1_200" class="footnote">Optimization</li><li id="footnote_2_200" class="footnote">Profile-Guided Optimization</li><li id="footnote_3_200" class="footnote"><span dir="rtl">به یاد استاد روحانی رانکوهی!</span></li><li id="footnote_4_200" class="footnote">Linux</li><li id="footnote_5_200" class="footnote">Windows</li><li id="footnote_6_200" class="footnote">Performance</li><li id="footnote_7_200" class="footnote">Build</li><li id="footnote_8_200" class="footnote">File</li><li id="footnote_9_200" class="footnote">Executable</li><li id="footnote_10_200" class="footnote">Run-time</li><li id="footnote_11_200" class="footnote">Compile-time</li><li id="footnote_12_200" class="footnote">Use case</li><li id="footnote_13_200" class="footnote">Compiling</li><li id="footnote_14_200" class="footnote">Linking</li><li id="footnote_15_200" class="footnote">Build System</li></ol>]]></content:encoded>
			<wfw:commentRss>http://blog.ebrahim.ir/1387/12/profile-guided-optimization/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk
Page Caching using disk (user agent is rejected)

Served from: blog.ebrahim.ir @ 2012-02-07 00:28:02 -->
