<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>cpu on tmtoku</title>
    <link>https://tmtoku.pages.dev/tags/cpu/</link>
    <description>Recent content in cpu on tmtoku</description>
    <generator>Hugo</generator>
    <language>ja</language>
    <lastBuildDate>Mon, 31 Aug 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://tmtoku.pages.dev/tags/cpu/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>整数除算は商のビット数が大きいほど遅い</title>
      <link>https://tmtoku.pages.dev/posts/micro-benchmark-integer-division/</link>
      <pubDate>Mon, 31 Aug 2026 00:00:00 +0000</pubDate>
      <guid>https://tmtoku.pages.dev/posts/micro-benchmark-integer-division/</guid>
      <description>&lt;p&gt;最近、&lt;a href=&#34;https://github.com/xoreaxeaxeax/asm-hall-of-shame&#34;&gt;Assembly Hall of Shame&lt;/a&gt; というプロジェクトを知りました。CPU 命令をどれだけ「遅く」実行できるかを競うもので、例えば x86 の &lt;code&gt;fxrstor64&lt;/code&gt; という命令は、条件次第で 1 回の実行に 1 分以上かけられるそうです。&lt;/p&gt;
&lt;p&gt;リーダーボードを眺めていて、整数除算命令 &lt;code&gt;idiv&lt;/code&gt; に目が止まりました。&lt;code&gt;idiv&lt;/code&gt; を遅くする方法の1つに、除数に対して被除数を大きくするということが挙げられています。
これを見て、入力値によって除算命令のレイテンシがどれくらい変わるのか気になりました。
というわけで本稿では、入力値の大きさを変えたときの整数除算命令 &lt;code&gt;idiv&lt;/code&gt; のレイテンシの変化を調べてみます&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;h2 id=&#34;レイテンシの定義&#34;&gt;レイテンシの定義&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;idiv&lt;/code&gt; は符号付き整数の除算命令です。64 ビットモードの場合、128 ビットの符号付き被除数を &lt;code&gt;RDX:RAX&lt;/code&gt; に入れ、64 ビットの除数をオペランドとして渡します。除算実行後、商は &lt;code&gt;RAX&lt;/code&gt;、余りは &lt;code&gt;RDX&lt;/code&gt; に入ります&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;p&gt;Zen 2 における各命令の典型的なレイテンシは、&lt;a href=&#34;https://docs.amd.com/v/u/en-US/56305&#34;&gt;Software Optimization Guide for AMD EPYC 7002 Processors&lt;/a&gt; に記載されています。64 ビットのオペランドに対する &lt;code&gt;idiv&lt;/code&gt; のレイテンシは 41 サイクルと書かれていますが、オペランドの値によるレイテンシの違いには触れられていません。
そもそも整数除算命令には2つの出力（商と余り）があるため、レイテンシには複数の定義が考えられます&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;が、そのあたりの詳細についても記述されていません。&lt;/p&gt;
&lt;p&gt;本稿では、整数除算命令のレイテンシを、実行開始から商と余りの両方を後続命令が利用できるようになるまでの時間、と定義します。&lt;/p&gt;
&lt;h2 id=&#34;ベンチマークの設計方針&#34;&gt;ベンチマークの設計方針&lt;/h2&gt;
&lt;p&gt;入力値の大きさを変えたときの &lt;code&gt;idiv&lt;/code&gt; のレイテンシの変化を計測するために、2つのベンチマークを用意します。&lt;/p&gt;
&lt;h3 id=&#34;被除数と商のビット数を変える&#34;&gt;被除数と商のビット数を変える&lt;/h3&gt;
&lt;p&gt;1つ目のベンチマークでは、除数を 1 に固定し、被除数を 2 のべき乗で変化させます。すなわち、被除数のビット数を &lt;span class=&#34;katex&#34;&gt;&lt;math xmlns=&#34;http://www.w3.org/1998/Math/MathML&#34;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mtext&gt; &lt;/mtext&gt;&lt;mo stretchy=&#34;false&#34;&gt;(&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo separator=&#34;true&#34;&gt;,&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo separator=&#34;true&#34;&gt;,&lt;/mo&gt;&lt;mo&gt;…&lt;/mo&gt;&lt;mo separator=&#34;true&#34;&gt;,&lt;/mo&gt;&lt;mn&gt;63&lt;/mn&gt;&lt;mo stretchy=&#34;false&#34;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&#34;application/x-tex&#34;&gt;b \,(= 1, 2, \ldots, 63)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; とおき、&lt;/p&gt;
&lt;span class=&#34;katex&#34;&gt;&lt;math xmlns=&#34;http://www.w3.org/1998/Math/MathML&#34; display=&#34;block&#34;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mtext&gt;dividend&lt;/mtext&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msup&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mrow&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;mo separator=&#34;true&#34;&gt;,&lt;/mo&gt;&lt;mspace width=&#34;1em&#34;/&gt;&lt;mtext&gt;divisor&lt;/mtext&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo separator=&#34;true&#34;&gt;,&lt;/mo&gt;&lt;mspace width=&#34;1em&#34;/&gt;&lt;mtext&gt;quotient&lt;/mtext&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msup&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mrow&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;mo separator=&#34;true&#34;&gt;,&lt;/mo&gt;&lt;mspace width=&#34;1em&#34;/&gt;&lt;mtext&gt;remainder&lt;/mtext&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&#34;application/x-tex&#34;&gt;
\text{dividend} = 2^{b-1}, \quad \text{divisor} = 1, \quad \text{quotient} = 2^{b-1}, \quad \text{remainder} = 0
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;p&gt;とします。除数を固定しているので、被除数とともに商も変化します。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
