読者です 読者をやめる 読者になる 読者になる

【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

整数の割り算を掛け算に変換 (4)

前回まで見てきた計算方法で、どれくらい高速化するか実験します。サンプルでは定数として10と97を使用します。Athlon 64 X2 4600+ 2.4GHzでの測定結果を掲載します。 div10 除算命令 div 80.66s div10mul 乗算命令 mul 16.14s div97 除算命令 div 82.46s di…

整数の割り算を掛け算に変換 (3)

前々回、前回に引き続き整数の割り算を掛け算に変換する方法について考えます。割り算を掛け算に変換するのは逆数を利用します。整数だけの計算では2以上の逆数がゼロになってしまうため、事前にx倍して後で割ります。 a / b = a * (1 / b) = a * (x / b) / …

整数の割り算を掛け算に変換 (2)

【注】この記事の計算方法は不完全なため誤差が出ます。次回以降で補正する方法を説明します。前回に引き続き整数の割り算を掛け算に変換する方法について考えます。単純化のため、計算対象を16bit符号なし整数型に限定します。除数が最大値の半分より大きい…

整数の割り算を掛け算に変換 (1)

【注】この記事の計算方法は不完全なため誤差が出ます。次回以降で補正する方法を説明します。コンパイラの出力を見ていると、除数が定数の場合に整数の割り算を掛け算に変換していることに気付きます。これがどんな原理で行われているのか考えてみました。…

void *とintptr_t

今まで何度かvoid *の説明を求められましたが、なかなか納得してもらえませんでした。説明を工夫するだけでは限界があると感じたので、別の方法でどうにかならないかを考えてみました。前回の記事の延長線上で説明します。サンプルコードを再掲します。 mov …

メモリ書き込み構文

対象環境を限定できる場合、バイト配列にリトルエンディアンで32bit値を書き込むときに、私は以下のように書いていました。 char buf[32]; *(int *)&buf[6] = 0x12345678; 非常に分かりにくいとご指摘を受けて色々と変形しましたが、どれもしっくり来ません…

文字列配列を作る (1)

数回に分けて文字列配列を作ってみます。手始めに検証用サブルーチンをJITで作ってみます。 strarray.c #include <stdio.h> #include <string.h> #include <windows.h> // for (i = 0; i < argc; i++) { // printf(argv[i]); // putchar(' '); // } char buf[] = { 0x56, // push esi 0x8b,</windows.h></string.h></stdio.h>…

関数のサイズ

第6回 コンパイラ実装会で出た話題です。関数のサイズを取ろうとしたら1になりました。なぜ? test.c #include <stdio.h> int main(void) { printf("%d\n", sizeof(putchar)); return 0; } 実行結果 $ gcc test.c $ ./a.exe 1int aへのポインタが&aであるように、putc</stdio.h>…