szktty #5306(2008/01/13 16:15 GMT) [ Other ] Rating0/0=0.00
Mac OS X (PowerPC 32bit) アセンブリで。profile 関数は func と同じ引数を持つ、func 専用の関数です。(表示するのは面倒だったので)実行時間をクロックカウントで返します。
PowerPCはリアルタイムクロックをサポートせず、その代わりに64bit(32bitレジスタ2つ)のタイムベースレジスタというレジスタが用意されています。しかしタイムベースレジスタの精度はCPUの実装依存でして、正確な計測は保証されません。
さらに、二つのレジスタの値を取り出す際に、下位32bitのレジスタ値の桁が繰り上がる場合があります。繰り上がった場合は状態レジスタ(MSR)のビットフラグが立ちますが、このレジスタにアクセスする命令が特権命令のため、通常のプログラムでは桁の繰り上がりを調べられません。というわけで桁の繰り上がりの考慮はあきらめています。
使用例:
#include <stdio.h> unsigned int profile(void (*fp)(int), int arg); void func(int n); void func(int n) { /* 処理 */ } int main() { printf("time -- %u\n", profile(func, 3)); return 0; }
see: mput の日記: PowerPC でもクロックカウント
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
.machine ppc .globl _profile ;; unsigned int profile(void (*fp)(int), int arg) ;; r3->r0: fp: 関数ポインタ ;; r4: int arg _profile: mr r0, r3 ; ポインタを別のレジスタにコピー mr r3, r4 ; 計測する関数の第一引数にする ;; レジスタをスタックに退避 mftb r4 ; タイムベースレジスタ stwu r0, -4(r1) stwu r3, -4(r1) stwu r4, -4(r1) mflr r12 ; リンクレジスタ stwu r12, -4(r1) ;; 関数呼び出し mtctr r0 ; カウントレジスタに関数ポインタをコピー bctrl ;; レジスタをスタックから復帰 lwz r12, 0(r1) mtlr r12 lwzu r4, 4(r1) lwzu r3, 4(r1) lwzu r0, 4(r1) addi r1, r1, 4 ;; 実行時間を返す mftb r3 ; 関数呼び出し後のタイムベースレジスタ sub r3, r3, r4 blr
Rating0/0=0.00-0+
[ reply ]
szktty
#5306()
[
Other
]
Rating0/0=0.00
Mac OS X (PowerPC 32bit) アセンブリで。profile 関数は func と同じ引数を持つ、func 専用の関数です。(表示するのは面倒だったので)実行時間をクロックカウントで返します。
PowerPCはリアルタイムクロックをサポートせず、その代わりに64bit(32bitレジスタ2つ)のタイムベースレジスタというレジスタが用意されています。しかしタイムベースレジスタの精度はCPUの実装依存でして、正確な計測は保証されません。
さらに、二つのレジスタの値を取り出す際に、下位32bitのレジスタ値の桁が繰り上がる場合があります。繰り上がった場合は状態レジスタ(MSR)のビットフラグが立ちますが、このレジスタにアクセスする命令が特権命令のため、通常のプログラムでは桁の繰り上がりを調べられません。というわけで桁の繰り上がりの考慮はあきらめています。
使用例:
#include <stdio.h> unsigned int profile(void (*fp)(int), int arg); void func(int n); void func(int n) { /* 処理 */ } int main() { printf("time -- %u\n", profile(func, 3)); return 0; }see: mput の日記: PowerPC でもクロックカウント
.machine ppc .globl _profile ;; unsigned int profile(void (*fp)(int), int arg) ;; r3->r0: fp: 関数ポインタ ;; r4: int arg _profile: mr r0, r3 ; ポインタを別のレジスタにコピー mr r3, r4 ; 計測する関数の第一引数にする ;; レジスタをスタックに退避 mftb r4 ; タイムベースレジスタ stwu r0, -4(r1) stwu r3, -4(r1) stwu r4, -4(r1) mflr r12 ; リンクレジスタ stwu r12, -4(r1) ;; 関数呼び出し mtctr r0 ; カウントレジスタに関数ポインタをコピー bctrl ;; レジスタをスタックから復帰 lwz r12, 0(r1) mtlr r12 lwzu r4, 4(r1) lwzu r3, 4(r1) lwzu r0, 4(r1) addi r1, r1, 4 ;; 実行時間を返す mftb r3 ; 関数呼び出し後のタイムベースレジスタ sub r3, r3, r4 blrRating0/0=0.00-0+
[ reply ]