<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>highly professional scums</title>
	
	<link>http://blog.gamedeff.com</link>
	<description>the place where select game development veterans rant about life, universe, and everything</description>
	<pubDate>Mon, 13 Jul 2009 08:50:49 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/Gamedeff" type="application/rss+xml" /><item>
		<title>Gamedeff party в Москве - 8 августа</title>
		<link>http://blog.gamedeff.com/?p=229</link>
		<comments>http://blog.gamedeff.com/?p=229#comments</comments>
		<pubDate>Mon, 13 Jul 2009 08:27:29 +0000</pubDate>
		<dc:creator>CEMEH</dc:creator>
		
		<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://blog.gamedeff.com/?p=229</guid>
		<description><![CDATA[Судя по всему, у нас таки получается вживую собраться в Москве субботним вечером и следует не упускать возможности.
Детали уточняются, но думаю по простому - хороший кабак, вкусный алкоголь, разговоры за интересное около геймдева и не только. Я со своей стороны буду счастлив поговорить за жизнь в корпорации, филейные части DirectX и графики в общем, и [...]]]></description>
			<content:encoded><![CDATA[<p>Судя по всему, у нас таки получается вживую собраться в Москве субботним вечером и следует не упускать возможности.</p>
<p>Детали уточняются, но думаю по простому - хороший кабак, вкусный алкоголь, разговоры за интересное около геймдева и не только. Я со своей стороны буду счастлив поговорить за жизнь в корпорации, филейные части DirectX и графики в общем, и прочая. Другие, я уверен, будут жечь еще ярче.</p>
<p>Ожидается известно какая тусовка, к нам обещают подтянуться из Питера и Воронежа. Присоединяйтесь, будет крута!<br />
Посему - если кто-то хочет с нами, отпишитесь плз в комментах, чтобы я мог оценить масштаб бедствия.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gamedeff.com/?feed=rss2&amp;p=229</wfw:commentRss>
		</item>
		<item>
		<title>Цена абстракции-4 (или все, что мама не рассказывала про C++)</title>
		<link>http://blog.gamedeff.com/?p=225</link>
		<comments>http://blog.gamedeff.com/?p=225#comments</comments>
		<pubDate>Fri, 03 Jul 2009 22:05:19 +0000</pubDate>
		<dc:creator>shodan</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.gamedeff.com/?p=225</guid>
		<description><![CDATA[Оказывается, за весь 2008й год не было ни одного поста про ценник абстракции.  Это недопустимо, надо исправлять.  Сегодня мы узнаем, как поиметь +30% в одну строчку, заменив if ( bool-flag ) на (int)bool-flag.
В коде случился такой паттерн: у объекта есть два указателя на разные куски в памяти, в зависимости от флажка надо выбирать [...]]]></description>
			<content:encoded><![CDATA[<p>Оказывается, за весь 2008й год не было ни одного поста про ценник абстракции.  Это недопустимо, надо исправлять.  Сегодня мы узнаем, как поиметь +30% в одну строчку, заменив if ( bool-flag ) на (int)bool-flag.</p>
<p>В коде случился такой паттерн: у объекта есть два указателя на разные куски в памяти, в зависимости от флажка надо выбирать либо по 1му, либо по 2му.  (Для справки, это некая статическая часть данных, которая расшарена между несколькими копиями объектов, и динамическая часть, которая очень личная и которой объект владеет).</p>
<p>Написал return bDynamic ? m_pDynamic[iOffset] : m_pStatic[iOffset], слегка задумался.  Поля m_pStatic и m_pDynamic в объекте лежат подряд.  bool bDynamic хоть и занимает целый байт, принимает все равно значения 0 и 1. Догадается компилятор заменить это дело на (*(&#038;m_pStatic+bDynamic))[iOffset], и выгоднее ли это?</p>
<p>Результаты MSVC 2005: да, выгоднее на 30%. Нет, не догадывается.</p>
<p>Результаты gcc 4.2.3: не уверен, что правильно понимаю ассемблерную нотацию, но похоже, догадывается сразу.  Поэтому разницу померить не удается, результаты одинаковые.</p>
<p>Код бенчмарка под катом.</p>
<p><span id="more-225"></span></p>
<div class="codesnip-container" >
<div class="codesnip">
<ol>
<li class="li1">
<div class="de1"><span class="co1">// cl /O2 perftest.cpp</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// shodan(at)shodan.ru</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co2">#include &lt;stdlib.h&gt;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co2">#include &lt;stdio.h&gt;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co2">#include &lt;time.h&gt; </span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co2">#ifdef _WIN32</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co2">#include &lt;windows.h&gt;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co2">#pragma comment(linker, &quot;/defaultlib:winmm.lib&quot;) </span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">typedef</span> __int64 int64_t;</div>
</li>
<li class="li1">
<div class="de1"><span class="co2">#else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co2">#include &lt;sys/time.h&gt;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co2">#define __forceinline inline</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co2">#endif</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">/// time since startup, in microseconds</span></div>
</li>
<li class="li1">
<div class="de1">int64_t sphMicroTimer<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co2">#ifdef _WIN32</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Windows time query</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">static</span> int64_t iStart = <span class="nu0">0</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">static</span> int64_t iFreq = <span class="nu0">0</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; LARGE_INTEGER iLarge;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> !iFreq <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; QueryPerformanceFrequency <span class="br0">&#40;</span> &amp;iLarge <span class="br0">&#41;</span>; iFreq = iLarge.<span class="me1">QuadPart</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; QueryPerformanceCounter <span class="br0">&#40;</span> &amp;iLarge <span class="br0">&#41;</span>; iStart = iLarge.<span class="me1">QuadPart</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; QueryPerformanceCounter <span class="br0">&#40;</span> &amp;iLarge<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span> iLarge.<span class="me1">QuadPart</span>-iStart <span class="br0">&#41;</span>*<span class="nu0">1000000</span>/iFreq;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co2">#else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// UNIX time query</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">static</span> <span class="kw4">int</span> s_sec = -<span class="nu0">1</span>, s_usec = -<span class="nu0">1</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">struct</span> timeval tv;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> s_sec == -<span class="nu0">1</span> <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; gettimeofday <span class="br0">&#40;</span> &amp;tv, <span class="kw2">NULL</span> <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s_sec = tv.<span class="me1">tv_sec</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s_usec = tv.<span class="me1">tv_usec</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; gettimeofday <span class="br0">&#40;</span> &amp;tv, <span class="kw2">NULL</span> <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> int64_t<span class="br0">&#40;</span>tv.<span class="me1">tv_sec</span>-s_sec<span class="br0">&#41;</span>*int64_t<span class="br0">&#40;</span><span class="nu0">1000000</span><span class="br0">&#41;</span> + int64_t<span class="br0">&#40;</span>tv.<span class="me1">tv_usec</span>-s_usec<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="co2">#endif // USE_WINDOWS</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw4">struct</span> Locator</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> m_iOffset;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">bool</span> m_bPart;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw4">struct</span> Foo</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> * m_pParts<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; __forceinline <span class="kw4">int</span> Getter1 <span class="br0">&#40;</span> <span class="kw4">const</span> Locator &amp; l <span class="br0">&#41;</span> <span class="kw4">const</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> l.<span class="me1">m_bPart</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? m_pParts<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#91;</span>l.<span class="me1">m_iOffset</span><span class="br0">&#93;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : m_pParts<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#91;</span>l.<span class="me1">m_iOffset</span><span class="br0">&#93;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; __forceinline <span class="kw4">int</span> Getter2 <span class="br0">&#40;</span> <span class="kw4">const</span> Locator &amp; l <span class="br0">&#41;</span> <span class="kw4">const</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> m_pParts<span class="br0">&#91;</span>l.<span class="me1">m_bPart</span><span class="br0">&#93;</span><span class="br0">&#91;</span>l.<span class="me1">m_iOffset</span><span class="br0">&#93;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">__forceinline <span class="kw4">int</span> Marker<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co2">#ifdef _WIN32</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; __asm</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; or eax,eax</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; or ebx,ebx</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; or ecx,ecx</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="co2">#else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; asm<span class="br0">&#40;</span><span class="st0">&#8220;orl %eax,%eax&#8221;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; asm<span class="br0">&#40;</span><span class="st0">&#8220;orl %ebx,%ebx&#8221;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; asm<span class="br0">&#40;</span><span class="st0">&#8220;orl %ecx,%ecx&#8221;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="co2">#endif</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">0</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw4">int</span> main <span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co2">#ifdef _WIN32</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; timeBeginPeriod <span class="br0">&#40;</span> <span class="nu0">1</span> <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="co2">#endif</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> dData1<span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="br0">&#123;</span> <span class="nu0">1</span>, <span class="nu0">2</span>, <span class="nu0">3</span> <span class="br0">&#125;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> dData2<span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="br0">&#123;</span> <span class="nu0">4</span>, <span class="nu0">5</span>, <span class="nu0">6</span> <span class="br0">&#125;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; Locator l;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">srand</span> <span class="br0">&#40;</span> <span class="kw3">time</span><span class="br0">&#40;</span><span class="kw2">NULL</span><span class="br0">&#41;</span> <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; l.<span class="me1">m_iOffset</span> = <span class="kw3">rand</span><span class="br0">&#40;</span><span class="br0">&#41;</span> % <span class="nu0">3</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; l.<span class="me1">m_bPart</span> = <span class="kw3">rand</span><span class="br0">&#40;</span><span class="br0">&#41;</span> % <span class="nu0">2</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">volatile</span> <span class="kw4">int</span> NRUNS = <span class="nu0">1000000</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">volatile</span> <span class="kw4">int</span> NOBJECTS = <span class="nu0">100</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; Foo * f = <span class="kw3">new</span> Foo <span class="br0">&#91;</span> NOBJECTS <span class="br0">&#93;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span> <span class="kw4">int</span> i=<span class="nu0">0</span>; i&lt;NOBJECTS; i++ <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; f<span class="br0">&#91;</span>i<span class="br0">&#93;</span>.<span class="me1">m_pParts</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> = dData1;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; f<span class="br0">&#91;</span>i<span class="br0">&#93;</span>.<span class="me1">m_pParts</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span> = dData2;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; int64_t t1 = -sphMicroTimer<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> iSum1 = <span class="nu0">0</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; Marker<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span> <span class="kw4">int</span> i=<span class="nu0">0</span>; i&lt;NRUNS; i++ <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span> <span class="kw4">int</span> j=<span class="nu0">0</span>; j&lt;NOBJECTS; j++ <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; iSum1 += f<span class="br0">&#91;</span>j<span class="br0">&#93;</span>.<span class="me1">Getter1</span> <span class="br0">&#40;</span> l <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; Marker<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; t1 += sphMicroTimer<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; int64_t t2 = -sphMicroTimer<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> iSum2 = <span class="nu0">0</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; Marker<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span> <span class="kw4">int</span> i=<span class="nu0">0</span>; i&lt;NRUNS; i++ <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span> <span class="kw4">int</span> j=<span class="nu0">0</span>; j&lt;NOBJECTS; j++ <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; iSum2 += f<span class="br0">&#91;</span>j<span class="br0">&#93;</span>.<span class="me1">Getter2</span> <span class="br0">&#40;</span> l <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; Marker<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; t2 += sphMicroTimer <span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co2">#ifdef _WIN32</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; timeEndPeriod <span class="br0">&#40;</span> <span class="nu0">1</span> <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="co2">#endif</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">printf</span> <span class="br0">&#40;</span> <span class="st0">&#8220;off=%d part=%d<span class="es0">\n</span>&#8220;</span>, l.<span class="me1">m_iOffset</span>, l.<span class="me1">m_bPart</span> <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">printf</span> <span class="br0">&#40;</span> <span class="st0">&#8220;sum1=%d time1=%d<span class="es0">\n</span>&#8220;</span>, iSum1, t1 <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">printf</span> <span class="br0">&#40;</span> <span class="st0">&#8220;sum2=%d time2=%d<span class="es0">\n</span>&#8220;</span>, iSum2, t2 <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span> </div>
</li>
</ol>
</div>
</div>
<p>На моем десктопе собранный MSVC 2005 вариант выдает</p>
<div class="codesnip-container" >
<div class="codesnip">
<ol>
<li class="li1">
<div class="de1">off=<span class="nu0">2</span> part=<span class="nu0">1</span></div>
</li>
<li class="li1">
<div class="de1">sum1=<span class="nu0">600000000</span> time1=<span class="nu0">133384</span></div>
</li>
<li class="li1">
<div class="de1">sum2=<span class="nu0">600000000</span> time2=<span class="nu0">102059</span> </div>
</li>
</ol>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.gamedeff.com/?feed=rss2&amp;p=225</wfw:commentRss>
		</item>
		<item>
		<title>про нерабочие логины</title>
		<link>http://blog.gamedeff.com/?p=222</link>
		<comments>http://blog.gamedeff.com/?p=222#comments</comments>
		<pubDate>Wed, 01 Jul 2009 19:54:08 +0000</pubDate>
		<dc:creator>shodan</dc:creator>
		
		<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://blog.gamedeff.com/?p=222</guid>
		<description><![CDATA[Все пишут, и я напишу.  Если вдруг не работает логин на блог с жалобами &#8220;Invalid registration status&#8221;, нужно отписать мне почтой, ОБЯЗАТЕЛЬНО сразу указав свой логин.  Перед собачкой надеюсь понятно что, после собачки геймдефф точка ком.  Чисто для справки, это антиспам плагин SABRE чудит, но отключать его нельзя (иначе спам опять заебет).
]]></description>
			<content:encoded><![CDATA[<p>Все пишут, и я напишу.  Если вдруг не работает логин на блог с жалобами &#8220;Invalid registration status&#8221;, нужно отписать мне почтой, ОБЯЗАТЕЛЬНО сразу указав свой логин.  Перед собачкой надеюсь понятно что, после собачки геймдефф точка ком.  Чисто для справки, это антиспам плагин SABRE чудит, но отключать его нельзя (иначе спам опять заебет).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gamedeff.com/?feed=rss2&amp;p=222</wfw:commentRss>
		</item>
		<item>
		<title>Побег из просторных офисов.</title>
		<link>http://blog.gamedeff.com/?p=208</link>
		<comments>http://blog.gamedeff.com/?p=208#comments</comments>
		<pubDate>Wed, 01 Jul 2009 17:51:04 +0000</pubDate>
		<dc:creator>IronPeter</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.gamedeff.com/?p=208</guid>
		<description><![CDATA[ У меня есть две новости.
Новость первая - в &#8220;Нивал Онлайн&#8221; ( или компания уже называется &#8220;Аструм Нивал&#8221;, я не в курсе ) открывается вакансия gfx программера. Работа не особо пыльная, если с надрочкой. Проект забавный, коллектив внятный ( Яся и Вова, куку ). Зарплату могут платить хорошую, как линейную функцию от скилла, с хорошим коэффициентом. [...]]]></description>
			<content:encoded><![CDATA[<p> У меня есть две новости.</p>
<p>Новость первая - в &#8220;Нивал Онлайн&#8221; ( или компания уже называется &#8220;Аструм Нивал&#8221;, я не в курсе ) открывается вакансия gfx программера. Работа не особо пыльная, если с надрочкой. Проект забавный, коллектив внятный ( Яся и Вова, куку ). Зарплату могут платить хорошую, как линейную функцию от скилла, с хорошим коэффициентом. Это я все без иронии, если что.</p>
<p>Менеджмент в компании разный - есть два менеджера, один добрый, второй соответственно не очень. Работают на контрастах.</p>
<p>Новость вторая. Мной подписано заявление об увольнении с 1 августа сего года, в связи с чем я ищу работу в стольном граде Москва. Можно в индустрии, можно за пределами. Умею писать под разное странное железо на низком уровне, вот успешно драйверцы для RSX зафигачил <a href="http://psp.jim.sh/svn/listing.php?repname=ps3ware&amp;path=%2Ftrunk%2Flibps3rsx%2Fsrc%2Finit%2Fps3rsx%2F">http://psp.jim.sh/svn/listing.php?repname=ps3ware&amp;path=%2Ftrunk%2Flibps3rsx%2Fsrc%2Finit%2Fps3rsx%2F</a>. Умею писать высокий уровень. Умею разное. По укурке защитил диссертацию по алгебраической топологии, уже работая в Нивале. Пожелание одно - работа без овертаймов. Я и с ними могу, если специально и заранее со мной согласовать, но у меня имеется стойкая аллергия на сей счет.</p>
<p>Не стесняйтесь c предложениями, пишите на IronSPeter &#8216;at&#8217; gmail.com. Только имейте в виду, что с 1 августа по 21 августа буду в безынтернетных далях и отвечать на заманчивые предложения не смогу. На новое место работы выйду с сентября, если найду внятную контору.</p>
<p>Под катом - неофициальная часть, отчасти грустная.</p>
<p><span id="more-208"></span></p>
<p>Есть такая отвратительная болезнь. Глаукома, необратимая атрофия зрительного нерва. Поле зрения сужается и превращается в замочную скважину, через которую человек смотрит на мир. А потом и вовсе&#8230; У меня этой дрянью болеет отец. Был май, Нивал распределял отпуска, мне вышел август. Отец попросил с ним поехать в родной город, я не отказался, сам он не сможет поехать.</p>
<p>Потом был июнь и менеджмент стал срочно искать, что урезать. Пытливый взор свеженазначенного менеджера Д.Д. наткнулся на отпуска. О! Предлагалось отложить личные дела, забыть привязанности и всей командой дружно поработать. Я запомнил фразу, формулировка меня привела в ступор. &#8220;Другое лето, другая первая любовь - все это еще у вас будет. А вот такого шанса зажечь - уже нет&#8221;.  Вроде я это действительно слышал, сам придумать такое не мог.</p>
<p>В связи с чем интересно.</p>
<p>С одной стороны имеем рассказы, что overtime оборачивается всегда undertime. Что многократно сорванные сроки - это всегда ошибка планирования, но никак не рядовых сотрудников. Что талантливые люди сгорают под нагрузками. И прочие другие азбучные истины менеджмента из книжек, которые читает Семен.</p>
<p>С другой стороны имеем забавное мнение менеджера Д.Д. Что искать в gamedev успешный проект без переработок, кранчей и сгорания на работе не имеет смысла. К лузерам попадете. Лучше сразу менять индустрию. Как вам такое мнение? Без эмоций только.</p>
<p>Петр.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gamedeff.com/?feed=rss2&amp;p=208</wfw:commentRss>
		</item>
		<item>
		<title>Reflections on Peopleware - Part 1</title>
		<link>http://blog.gamedeff.com/?p=204</link>
		<comments>http://blog.gamedeff.com/?p=204#comments</comments>
		<pubDate>Wed, 01 Jul 2009 08:10:35 +0000</pubDate>
		<dc:creator>CEMEH</dc:creator>
		
		<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://blog.gamedeff.com/?p=204</guid>
		<description><![CDATA[Ай-ай-ай, как же это я забыл закросспостить. Исправляюсь.
Пока Windows7 неумолимо движется к завершению (FTW), на работе спадают страсти, свирепствует грипп, а погода меняется от замечательной к обычной, я сижу дома и читаю книжки. Я
теперь почти везде читаю - аудиокнижки завоевывают жизнь в автомобиле и оттуда осаждают спорт и быт.
Вот, например, я несколько месяцев назад таки [...]]]></description>
			<content:encoded><![CDATA[<p>Ай-ай-ай, как же это я забыл закросспостить. Исправляюсь.<br />
Пока Windows7 неумолимо движется к завершению (FTW), на работе спадают страсти, свирепствует грипп, а погода меняется от замечательной к обычной, я сижу дома и читаю книжки. Я<br />
теперь почти везде читаю - аудиокнижки завоевывают жизнь в автомобиле и оттуда осаждают спорт и быт.</p>
<p>Вот, например, я несколько месяцев назад таки осилил классику софтверного project management - <a href="http://www.amazon.com/Peopleware-Productive-Projects-Teams-Second/dp/0932633439">Peopleware</a> ДеМарко и Листера.</p>
<p>У меня смешанные ощущения. Как и в любой хорошей книжке, там много мыслей и авторских впечатлений,  некоторые мне очень нравятся, некоторые меньше, по куче вопросов у меня нет мнения. Но она вся такая светлая и хорошая (я бы даже сказал, светлоджедайская), зажигает и мотивирует.</p>
<p>Давайте я очень тезнисно эти мысли запишу и попробую прорефлексировать с точки зрения устройства вещей в MS. Если заодно и вы свои мысли выскажете, то значит совсем не зря книжку прочитал - азбучные вопросы  обсуждать очень полезно.</p>
<p><span id="more-204"></span><br />
Первая часть - про сравнение софтвера с традиционным производством.</p>
<p>Говорят очевидные вещи - что <b>development очень отличается от production</b> (у нас, слава богу, стоимость production нулевая), процессам вредит излишняя стандартизация - главная задача исполнителя думать, нельзя процессами компенсировать работу мозга.<br />
Уточняют отличия - спокойнее относиться к ошибкам, так как все новое и многое не узнать, пока не попробуешь; не помогает людей пинать, потому что от пинков быстрее думать не начинаешь; заменять людей очень тяжело, медленно и дорого.</p>
<p><i>Что тут сказать&#8230; well, duh (но надо помнить, это книжка 1987 года).</i> </p>
<p>Следующий набор мыслей про <b>последствия давления на людей</b>:<br />
- овертайм _всегда_ приводит к такому же или большему undertime - т.е. люди как минимум такое же количество времени работают менее продуктивно. Это легко не заметить.<br />
- у овертайма есть долговременные последствия - жизнь проходит мимо<br />
- с трудоголиками нужно очень осторожно - если додавливать до предела, то рано или поздно сгорят с концами<br />
- самое дорогое последствие овертайма - как влияет на текучку кадров. Пишут, никто не даже не пытается оценить этот фактор.<br />
- People under time pressure don&#8217;t work better, they just work faster.</p>
<p><i>В Windows (да и вообще в MS) в этом смысле все очень хорошо. У меня за два года кранчи случались всего пару раз и длились не больше недели, менеджеры не наседают и почти никогда не предлагают поработать по выходным. У меня был тиммейт, который именно поэтому пришел в MS из геймдева и даже не думал обратно.<br />
С другой стороны, если ты сам хочешь въебывать - сколько угодно, и если у тебя получается продуктивно - это конечно окупается. То есть, прецеденты, когда отсутствие жизни очень помогает в карьере, я видел. Видел хорошие карьеры и без этого, впрочем. Что логично - если получается больше делать, это приемущество, но надо еще знать что.</i></p>
<p>Еще у них неожиданные наблюдения про <b>&#8220;качество против времени&#8221;</b>.<br />
Во-первых, что делать некачественный продукт люди не любят (с последствиями). Это понятно.<br />
Во-вторых, что внутренний стандарт качества исполнителей типично выше необходимого менеджменту (даже сильнее, маркету). Это допустим.<br />
И в-третьих, неожиданное - от повышения качества вне необходимого растет продуктивность, потому что мол больше мотивации и люди начинают работать над процессами и тулами, которые окупаются.</p>
<p><i>Я прям не знаю. Я очень хорошо вижу, что в Windows (и, по рассказам, в Office) от размера проекта и очень высокого качества кода (да-да, очень высокого) все очень медленно. Багфиксинга - более 50% времени разработки, чинить один баг в день - хорошо, а два - подвиг. Тест-команда такого же размера и квалификации, что дев - ибо полностью покрывать Windows автоматическими тестами.<br />
С другой стороны, быстрый билд, очень мощный отладчик, тулзы для code review и прочее-прочее. Может, если изначально туда бы не целились, и вообще бы не взлетело. Возможно, они хотят сказать, что нужно инвестировать в инфраструктуру дальше, чем на сейчас.<br />
А у вас есть мнение? </i></p>
<p>Последний их тезис на сегодня - <b>Parkinson&#8217;s Law revisited</b>.<br />
Все знают, что такое закон Паркинсона - работа занимает все выделенное на нее время, вне зависимости от его количества.<br />
Они считают, что к нам с вами он не применим, потому что мы в основном получаем удовлетворение от сделанной работы и понимаем, что жизнь коротка, и хочется многое успеть. Считают, что если в хорошей команде кто-то никак не может что-то закончить - это чаще не из-за лени. И даже когда из-за лени - то лучше если пинают товарищи по команде, чем менеджер.<br />
(я уже говорил, что это светлая и добрая книжка?)<br />
Приводят некие исследования, в которых измеряется продуктивность в зависимости от установления срока. Хуже всего, когда срок оценивает менеджер (и он получается самым маленьким), лучше - когда сам, еще лучше - когда без оценки.</p>
<p><i>Про слабую корреляцию агрессивного дедлайна/пинания жопы с производительностью -  я согласный (что через вопросы &#8220;как там?&#8221;, что через менеджерское дилдо). С возрастом я скорее более прямо говорю &#8220;нет, это займет вот столько&#8221; и &#8220;я тут проебал, надо больше времени&#8221; и на пинки реагирую все спокойнее. (Джоэль, кажется, <a href="http://www.joelonsoftware.com/items/2007/10/26.html">об этом же пишет</a>)<br />
Важный момент, мне кажется - дело скорее не в распиздяйстве, а в размазывании фокуса, т.е. когда начинаешь много тратить времени на необязательные возникшие проблемы. Но опять же, это не вылечить наличием дедлайна - это опыт, это &#8220;узнавать о проблеме рано и поправлять расписание&#8221;.<br />
Одним словом, не верю я в мотивацию сроками, но верю, что помогает фокусу.<br />
 </i></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gamedeff.com/?feed=rss2&amp;p=204</wfw:commentRss>
		</item>
		<item>
		<title>one-liner</title>
		<link>http://blog.gamedeff.com/?p=203</link>
		<comments>http://blog.gamedeff.com/?p=203#comments</comments>
		<pubDate>Tue, 02 Jun 2009 21:42:51 +0000</pubDate>
		<dc:creator>shodan</dc:creator>
		
		<category><![CDATA[one-liners]]></category>

		<guid isPermaLink="false">http://blog.gamedeff.com/?p=203</guid>
		<description><![CDATA[Ссыте By The Bay.
]]></description>
			<content:encoded><![CDATA[<p>Ссыте By The Bay.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gamedeff.com/?feed=rss2&amp;p=203</wfw:commentRss>
		</item>
		<item>
		<title>Сказ про то, как American Chopper сам восстановился</title>
		<link>http://blog.gamedeff.com/?p=202</link>
		<comments>http://blog.gamedeff.com/?p=202#comments</comments>
		<pubDate>Thu, 07 May 2009 05:57:17 +0000</pubDate>
		<dc:creator>dDIMA</dc:creator>
		
		<category><![CDATA[debugging]]></category>

		<category><![CDATA[problems]]></category>

		<category><![CDATA[tips-n-tricks]]></category>

		<guid isPermaLink="false">http://blog.gamedeff.com/?p=202</guid>
		<description><![CDATA[А я вот вчера вечером решил поностальгировать и поставил себе на домашний комп American Chopper. Не, на самом деле, конечно, я хотел кое что в нем посмотреть, но будем считать это простой ностальгией. Проект уже старенький, 5 лет прошло, к тому же он (сейчас это уже хорошо видно) цинично спортирован с PS2 версии с самыми [...]]]></description>
			<content:encoded><![CDATA[<p>А я вот вчера вечером решил поностальгировать и поставил себе на домашний комп American Chopper. Не, на самом деле, конечно, я хотел кое что в нем посмотреть, но будем считать это простой ностальгией. Проект уже старенький, 5 лет прошло, к тому же он (сейчас это уже хорошо видно) цинично спортирован с PS2 версии с самыми минимальными переделками. Но речь сейчас не об этом.</p>
<p>В Крейтовском коде еще с прошлого века существовал блок функций SetIdle()/ClearIdle()/IsIdle(). Эти функции предназначены для работы с режимом паузы. SetIdle() увеличивает счетчик паузы, ClearIdle() - уменьшает. Если счетсик равен 0, игра находится в рабочем состоянии. Если &gt; 0, игра находится в режиме паузы. Внутриигровое меню, например, на конструкторе ставит режим паузы, на деструкторе ее снимает. Железобетонно? Вроде как да.</p>
<p><span id="more-202"></span>Тем не менее, одновременно с этими функциями был сделан следующий код в момент начала загрузки каждого нового уровня:</p>
<div class="codesnip-container" >if (m_idleCounter &gt; 0)<br />
{<br />
Warning(&#8221;Resetting pause mode&#8221;);<br />
m_idleCounter = 0;<br />
}</div>
<p>Так вот. Играю я вчера в American Chopper, врезаюсь в очередную машину, меня в воздухе ловит камера, ставит паузу, показывает со всех сторон, я прерываю этот скрипт Enter&#8217;ом, и происходит чудо. Впервые за все время разработки в Крейте, за все время локализации в 1С (я заканчивал проект, уже работая тут), <strong>игровой скрипт не снимает режим паузы при прерывании показа</strong>. То есть скрипт отработал, а я лежу себе на дороге такой красивый загораю, а посадить себя в мотоцикл и поехать дальше не могу.</p>
<p>Впрочем, работает внутриигровое меню, я перезагружаю уровень, и несмотря на то, что в протокол ушло &#8220;Resetting pause mode&#8221;, следующий уровень начал играть нормально. Больше мне ни разу не удалось вызватьтакое поведение скрипта, я даже предположить не могу, с чем было связано такое поведение. Возможно, с быстрым 4-х ядерным процессором. Возможно, я попал Enter&#8217;ом в какую-то наносекунду, куда не мог попасть раньше. А возможно, скрипт также фатально прервал свою работу, потому что что-то случилось где-то еще в программе. Но самое главное, что программа восстановилась после такого сбоя и позволила пользователю продолжать работать дальше.</p>
<p>На самом деле здесь неработоспоосбность программы и ее восстановление являются визуально очевидными. Однако в вашем коде бывает огромное количество мест, когда наступившее рассогласование с реальностью проявится сильно позже, либо проявляется только на определенной конфигурации компьютера.</p>
<p>Я в следующей статье покажу, каким образом выражение вида</p>
<div class="codesnip-container" >int a = 0;<br />
&#8230;<br />
a = 0; // на всякий случай</div>
<p>из неумелой заклейки, выполненной студентом первого курса превращается в мощный инструмент, который позволяет с одной стороны, заметно быстрее отлаживаать код и находить в нем ошибки, а с другой стороны, является хорошим средством для восстановления программы даже в достаточно критических ситуациях.</p>
<p>Мораль: если у вас есть переменная int alwaysZeroValue = 0; то иногда она будет ненулевой.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gamedeff.com/?feed=rss2&amp;p=202</wfw:commentRss>
		</item>
		<item>
		<title>Мифический текстурный шейдер (мексиканская история)</title>
		<link>http://blog.gamedeff.com/?p=201</link>
		<comments>http://blog.gamedeff.com/?p=201#comments</comments>
		<pubDate>Sun, 03 May 2009 22:36:34 +0000</pubDate>
		<dc:creator>look4awhile</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.gamedeff.com/?p=201</guid>
		<description><![CDATA[А, собственно, зачем? Казалось бы, всё итак успешно можно решать прямо на уровне пиксельных шейдеров.

Такая абстракция очевидно толще, чем позволяет формат мексиканской истории, особенно в 5 утра. (Здесь аффтор долго думает грустные мысли о том, кому и зачем он всё это пишет). Как обычно читателям придётся много додумать, но в этот раз, мне кажется, уместно [...]]]></description>
			<content:encoded><![CDATA[<p>А, собственно, зачем? Казалось бы, всё итак успешно можно решать прямо на уровне пиксельных шейдеров.<br />
<span id="more-201"></span><br />
Такая абстракция очевидно толще, чем позволяет формат мексиканской истории, особенно в 5 утра. (Здесь аффтор долго думает грустные мысли о том, кому и зачем он всё это пишет). Как обычно читателям придётся много додумать, но в этот раз, мне кажется, уместно нетривиальное обсуждение.</p>
<p>Начнём, впрочем, с конца. Внятная новая абстракция кроме собственно инноваций очевидно успешно решает уже имеющиеся проблемы.</p>
<p>Сперва абстракция. Итак float4 TexBlah(float4 coordinates). Будем резать. Очевидных линий отреза две: прямо на уровне TexBlah, либо на уровень ниже фильтрации. Нужен-ли шейдер фильтрации я буду думать потом, а пока что отрежем на уровне текстурного сэмпла. float4 SampleTexBlah(int4 coordinates). Уровень TexBlah имеет свои приимущества, но идёт вопреки идее грубой силы – и потому лесом.</p>
<p>Теперь немножко про зачем. И про почему. Шейдеры остаются не менее унифицированные, добавляется дополнительный паралеллизм. На каждый TexBlah сэмплов будет чаще всего значительно больше одного. С очень когерентными coordinates. Появляется дополнительное кеширование. SampleTexBlah определённо функция без сайд-эффектов.</p>
<p>Кеширование, кстати, ставит интересный вопрос. Float4 SampleTexBlah(int4 coordinates) очевидно проигрывает byte4 SampleTexBlah(int4 coordinates) – формат результата зависит от формата текстуры, а для случая DXT1 (которое на современном железе хранится в кеше в нераспакованом виде) придумать внятный формат результата у меня почти не получается. Т-е вопрос исключительно эффективности кеша, и здесь однозначного мнения у меня нет (интруция говорит ограничимся byte4 снизу и float4 сверху). Собственно здесь снова встаёт вопрос шейдера фильтрации, но это, пожалуй, единственный имеющийся у меня use-case.</p>
<p>В итоге очередной кусок специализированного железа (а есть ли он там?) получает равноправное унифициорванное применение. Пусть будет 2x нитей, а не ещё несколько текстурных блоков. Такая система будет значительно лучше масштабироваться.</p>
<p>Как всё это может выглядеть? Ну, например, вот так</p>
<div class="codesnip-container" >byte4 palette[256];<br />
byte [] index_map;<br />
int width, height;</p>
<p>byte4 main ( int2 coordinates )<br />
{<br />
  byte index = index_map[coordinates.x+coordinates.y*width];<br />
  return palette[index];<br />
}</p></div>
<p>Теперь, когда как-то понятно, где оно работает, вернёмся снова к предмету обсуждения. А, собственно, зачем?</p>
<p>Пример выше иллюстрирует мой самый первый use-case. А именно поддержка текстур с палитрой на современном железе. Я ничего не буду говорить про компрессию, мегатекстуры, фрагментацию текстурной памяти и прочие самоочевидные вещи. Замечу, только, что работать такое будет значительно лучше, чем сколь угодно продуманный фиксированный API. Меньше всего я хочу удвидеть очередную видеокарту с аппаратной поддержкой мегатекстур. Надеюсь имеющиеся “фенечки” про стенсильный буфер тоже когда-нибудь кто-нибудь выкинет на свалку истории, хотя-бы какими-нибудь бленд-шейдерами. Но это уже тема совсем другой истории.</p>
<p>P.S. ужасно уродливый шейдер про текстуру с палитрой и билинейной фильтрацией могу отдать в хорошие руки.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gamedeff.com/?feed=rss2&amp;p=201</wfw:commentRss>
		</item>
		<item>
		<title>Проще, легче, меньше!</title>
		<link>http://blog.gamedeff.com/?p=200</link>
		<comments>http://blog.gamedeff.com/?p=200#comments</comments>
		<pubDate>Tue, 28 Apr 2009 11:05:22 +0000</pubDate>
		<dc:creator>_winnie</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.gamedeff.com/?p=200</guid>
		<description><![CDATA[Программисты злятся и приходят к геймдизу когда задание неконкретное, просят конкретики. Они её получают, но часто им это не нужно. Нужен совершенно конкретный пункт «всё равно как сделать» или «можно так, так и вот так». Случайное, но конкретное решение съест много времени. Хотя можно было бы выбрать самое дешёвое, по времени реализации. Типично может быть [...]]]></description>
			<content:encoded><![CDATA[<p>Программисты злятся и приходят к геймдизу когда задание неконкретное, просят конкретики. Они её получают, но часто им это не нужно. Нужен совершенно конкретный пункт «всё равно как сделать» или «можно так, так и вот так». Случайное, но конкретное решение съест много времени. Хотя можно было бы выбрать самое дешёвое, по времени реализации. Типично может быть «полдня vs полтора дня». Хорошо если не неделя.</p>
<p>Ленивый код: любая фича добавляется по нужде. У класса Image есть метод CropRight, для прогресс-баров. CropLeft, CropTop, CropBottom пока не понадобились.</p>
<p>Когда непонятно, как сделать быстро и дёшево – отложить на несколько дней, часто простое и оригинальное решение приходит в голову внезапно, пока возишься с другим тасками. Или вообще проблема отпадает сама собой.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gamedeff.com/?feed=rss2&amp;p=200</wfw:commentRss>
		</item>
		<item>
		<title>Чем должна и не должна заниматься игра на старте?</title>
		<link>http://blog.gamedeff.com/?p=198</link>
		<comments>http://blog.gamedeff.com/?p=198#comments</comments>
		<pubDate>Fri, 24 Apr 2009 07:48:09 +0000</pubDate>
		<dc:creator>dDIMA</dc:creator>
		
		<category><![CDATA[problems]]></category>

		<category><![CDATA[tips-n-tricks]]></category>

		<guid isPermaLink="false">http://blog.gamedeff.com/?p=198</guid>
		<description><![CDATA[Спасибо огромное всем, кто проголосовал в опросе (увы, пока движок блога не позволяет размещать опросы здесь, приходится их делать у себя в ЖЖ).
Как обычно, результаты очень показательные, особенно если учесть возможность посмотреть ответы и сравнить выпущенные разработчиками игры.
Я озвучу свою собственную точку зрения на вопрос &#8220;требуется ли такая диагностика в игре и если да, то [...]]]></description>
			<content:encoded><![CDATA[<p>Спасибо огромное всем, кто <a href="http://ddima.livejournal.com/54498.html" _fcksavedurl="http://ddima.livejournal.com/54498.html">проголосовал в опросе</a> (увы, пока движок блога не позволяет размещать опросы здесь, приходится их делать у себя в ЖЖ).</p>
<p>Как обычно, результаты очень показательные, особенно если учесть возможность посмотреть ответы и сравнить выпущенные разработчиками игры.</p>
<p>Я озвучу свою собственную точку зрения на вопрос &#8220;требуется ли такая диагностика в игре и если да, то каким образом ее делать&#8221;. Кстати судя по ответам, по состоянию на 11:47 24 апреля я должен растаться с 29 литрами пива (именно столько людей проголосовало за пункт 1). Впрочем, пиво почти наверняка останется при мне, потому что я готов привести конфигурации компьютеров и настроек, на которых ваша версия GetTotalVideomem() даст неправильный ответ.</p>
<p>А раз вы не можете быть уверены в результате, то что же делать?</p>
<p class="ljcut"><span id="more-198"></span>Разумеется, очевидно, что для PC-игр конфигурация компьютера может быть сильно различной. И для борьбы с этим явлением многие разработчики вынуждены вводить видео-опции. Кто-то вводит технологические опции, такие так &#8220;Lightmaps&#8221;, &#8220;Texture filtering&#8221;, &#8220;HDR&#8221; и т.п., кто-то - более игровые &#8220;Render quality&#8221; и т.п. Ну и иногда делаются кнопки типа &#8220;максимальное качество&#8221; / &#8220;сбалансированные настройки&#8221; / &#8220;минимальные настройки&#8221;. Хотя настройки типа Lightmaps/Shadows позволяют (наверное) сбалансировать качество vs производительность лучше, чем один ползунок &#8220;Render quality&#8221;, не совсем понятно, какое количество игроков будет готово заниматься таким тщательным тюнингом.</p>
<p>Но речь даже не об этом. Стремление помочь игроку в познании игры в ее максимальном качестве иногда приводит к совершенно невообразимым результатам. Из них вполне получился бы такой же &#8220;Топ 10&#8243;, какой я делал про <a href="http://ddima.livejournal.com/49050.html" _fcksavedurl="http://ddima.livejournal.com/49050.html">самые нелепые падения игр</a>. Установка игре high process priority и автоматическая блокировка процесса icq.exe - это еще не самое страшное, что может быть. Требование на определенный размер своп файла - это уже веселее. Требование на /3Gb пока еще не встречал, и слава богу. Но это все меркнет перед тем, на какие реальные шаги разработчики готовы пойти, ради того, чтобы оградить пользователя от плохого впечатления от игры, вызванного низкой производительностью&#8230;</p>
<p>К сожалению, очень часть эта задача (как и многие другие) решаются не от точки зрения конечного пользователя, а с точки зрения программиста, который скоцентировался на конкретной задаче (при запуске игры выставить правильную конфигурацию), и в упор не видит альтернативные решения, а самое, главное, какие проблемы он пытается решить и какие новые проблемы порождает.</p>
<p>Я хотел бы развеять несколько мифов.</p>
<p>Миф номер 1. Вы можете определить конфигурацию компьютера. На сам деле ни хера вы не можете. Даже тактовую частоту процессора вы не определите. А даже если и определите (и даже если еще про количество ядер не забудете), что вам это даст? И вы уверены, что тактовая частота больше 4294967296 Гц не вызовет в вашей программе переполнения int? Про видеопамять уже писал выше, даже повторяться не буду. Вы конечно можете потратить несколько человеко-месяцев на борьбу с текущим детектированием конфигурации компьютера и несколько человеко-месяцев на борьбу с будущими конфигурациями (примеры ниже). Но это все равно бесперспективно.</p>
<p>Миф номер 2. Пользователю требуется регулярная проверка конфигурации компьютера и установка параметров в автоматическом режиме. Ни хрена. Он будет благодарен вам, если вы настроите игру в момент инсталляции. Если он купит другую железку или покрутит настройки в биосе, то он достаточно опытен, чтобы найти окно &#8220;Video options&#8221;. Если хотите совсем казуального решения - сделайте отдельную утилиту &#8220;Автоматическое детектирование конфигурации компьютера&#8221;, чтобы она переустановила настройки игры (альтернативный вариант - ключ запуска игры типа -reset - приведен ниже).</p>
<p>Миф номер 3. Игра должна блокировать свой запуск, если конфигурация компьютера не соответствует системным требованиям. Поскольку миф номер 1 - это действительно миф, то блокировка запуска игры - это самый худший вариант, который вы можете предложить игроку. Вы можете сообщить, что его компьютер плохой, и что он может не потянуть с нужной производительностью (Continue/Cancel). Вы можете сообщить, что из-за капсов у него что-то не будет рисоваться или рисоваться с глюками или даже вообще программа может упасть. Но физически запрещать запуск игры - я надеюсь, что среди издаваемых нами продуктов я такого больше не увижу. Потому что когда появился Core 2 Duo некоторые наши игры начали выдавать следующий перл: &#8220;<em>Ваш компьютер имеет тактовую частоту 2.1 ГГц. Для игры требуется 3 ГГц. Нажмите Ok,. чтобы выйти из программы</em>&#8221; (это еще к мифу номер 1).</p>
<p>На самом деле, какие вопросы надо решить разработчику:<br />
1. Надо, чтобы игра установилась на компьютер;<br />
2. Надо, чтобы она &#8220;по умолчанию&#8221; работала достаточно адекватно;<br />
3. Надо, чтобы ни при каком развитии событий у пользователя не возникло дедлока, что он не может запустить игру (разумеется, про критические рантайм ошибки речь не идет);<br />
4. Надо, чтобы ее запуск не отжирал продолжительное время;<br />
5. Надо, чтобы у продвинутого пользователя была возможность настроить / отбалансить игру под свой компьютер и под себя;<br />
6. Надо, чтобы у обычного &#8220;казуального&#8221; пользователя при помощи службы техподдержки была возможность дистанционно решить какие-то проблемы или настроить игру под свой компьютер.</p>
<p>Пункты 1 и 2 приводят нас к тому, что в процессе установки игра может проверить конфигурацию компа и предложить свой вариант для установки параметров по умолчанию. Если она такого делать не умеет - поставьте настройки в среднее значение, чтобы игра нормально запустилась на большинстве компьютеров. Если есть, если детектор отработал без падений (учитывая объем кода для того, чтобы вытащить размер видеопамяти из dxdiag, это важное замечание) и если его результатам можно доверять, поставьте настройки так, как считаете нужным.</p>
<p>Пункт 3 вроде бы как приводит нас к тому, что надо детектировать конфигурацию на каждом запуске. На самом деле не надо (пункт 4 запрещает нам делать это). И в наших техтребованях, и у многих других издателей есть пункт о том, что нужна либо отдельная программа, либо опция командной строки, которая позволяет обресетить все настройки игры и запустить ее в минимальном качестве. Делается за сутки, работает надежно на любой конфигурации.</p>
<p>И наконец, пункты 5 и 6 могут быть реализованы в игре при помощи каких-то дополнительных переключателей и настроек. Не обязательно даже в графическом режиме. Можно в текстовом файле при помощи команд set. Можно так, как это сделано в firefox (about:config). Можно как угодно. Желательно, чтобы эта возможность была, но при этом абсолютно не мешала 99% пользователей, которым это никогда не понадобится.</p>
<p>А освободившееся время лучше потратьте на профилирование и улучшение производительности. Пользователи вам будут намного более благодарны, чем если вы будете на каждом старте игры детектировать конфигурацию и &#8220;не пущать&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gamedeff.com/?feed=rss2&amp;p=198</wfw:commentRss>
		</item>
	</channel>
</rss>
