SlideShare a Scribd company logo
1 of 41
Download to read offline
あるコンテキストスイッチの話
えとみ なるあき
OSC名古屋
Kernel/VM探検隊@北陸
お約束
※ コンテキストスイッチのやりかたはいくつか方法(setjmp,longjmpなど)が
あると思いますが、 setjmp,longjmpなどは今回は扱いません。
※ MPカーネルも扱いません...(頭が追いついていないので(´・ω・`))
※ wikipediaのコンテキストスイッチの項目をあらかじめ読んでおくと、
よりいっそう楽しめる内容になっております。
※ trapb命令は覚えておくと良いキーワードです。
※ exception_return()でFPUをON/OFしているというのは重要です。
※ ぴょんぴょんも重要キーワードです。
※ 予習→実装という流れでお話は進みます!
ソースコードはおまけです!
資料のCPUはalphaですがarm、 mips、powerpc
全て実装が違います。
この資料を読んで概念を身につけたあとに、
一人でも自分の好きなCPUの実装を調べた方がいらっしゃったら嬉しいです
これまでのあらすじ
※ ある日のNetBSD/alpha currentでtopをすると
Floating point exceptionでcore dumpする
という事件が発生した!
※ PR-48782でgccのバグだと勘違いして主張してみた!(libmのコンパイルオプションが変更されてた)
“ I think that this case is -mieee-with-inexact option bug.”
※ とりあえず変更はrevretされたので自分でも独自調査
“I think that trapb instruction incompatible with fpu_state_load().”と返答し
へぼパッチを投げる
“lazy FPU context switch”って何?調べてみました!
※ その後、いろいろやりとりして、topのバグでもなく、gccのバグでもなく
カーネルのlazy FPU context switchのコードがバグっていたという結論がでた!
まずコンテキストスイッチとは何なのか?
コンテキストスイッチ (context switch) とは、
複数のプロセスが1つのCPUを共有できるように、
CPUの状態(コンテキスト)を保存したり復元したりする過程のことである。
コンテキストスイッチはマルチタスクオペレーティングシステムに不可欠な機能である。
通常コンテキストスイッチは多くの計算機処理を必要とするため、
オペレーティングシステムの設計においてはコンテキストスイッチを最適化することが重要である。
コンテキストスイッチでは、実行中のプロセスの状態を何らかの方法で保存し、
後にそのプロセスを再開する際にその状態を復元して、
正常に実行を継続できるようにしなければならない。
プロセスの状態には、そのプロセスが使用し得る全てのレジスタ(特にプログラムカウンタ)や、
プロセスの実行に必要となるオペレーティングシステム固有の情報が含まれる。
wikipediaより
ぴょんぴょん
つまりOSのなかでプロセスがぴょんぴょんしている訳ですね!
mi_switch()
ご注文はどのLWPですか?
描いてみた
sh
mi_switch syslog
mi_switch mikutter(ruby)
mi_switch mlterm
shmi_switch
コンテキストスイッチ
コンテキストスイッチ
コンテキストスイッチ
コンテキストスイッチ
コンテキストスイッチするとき、
実行中のプロセスの状態を「どこ」に保存しているのか?
PCB(Process control block)
PCB is 何?
Alphaの浮動小数点レジスタは
64bit X 32本+ FPUコントロールレジスタ
swpctx命令でコンテキストされる
/src/sys/arch/alpha/include/alpha_cpu.h src/sys/arch/alpha/include/pcb.h
src/sys/arch/alpha/include/reg.h
予習として描いてみた(ポルナレフもビックリっーか…)
mikutterのプロセス
mltermのプロセス
CPU
実行中のmikutterから
mltermにスイッチ
不思議な力で
次の実行プロセスは
mltermに決定
mikutterプロセスのPCBに
CPUのレジスタとか保存
mltermプロセスのPCBの内容
をCPUにロード
『The WORLD』 オレだけの時間だぜ
CPU
実行中のmltermから
mikutterにスイッチ
不思議な力で
次の実行プロセスは
mikutterに決定
mltermプロセスのPCBに
CPUのレジスタとか保存
mikutterプロセスのPCBの内容
をCPUにロード
『時』は動き出す….
では実装
(コンテキストスイッチをするところ)
mi_switchの実装
/*
* The machine independent parts of context switch.
*
* Returns 1 if another LWP was actually run.
*/
int
mi_switch(lwp_t *l)
{
struct cpu_info *ci;
struct schedstate_percpu *spc;
struct lwp *newl;
int retval, oldspl;
struct bintime bt;
bool returning;
……….
/* Switch to the new LWP.. */
prevlwp = cpu_switchto(l, newl, returning);
ci = curcpu();
/*
* Switched away - we have new curlwp.
* Restore VM context and IPL.
*/
pmap_activate(l);
uvm_emap_switch(l);
pcu_switchpoint(l);
/sys/kern/kern_synch.c l
newl
lの情報(PC等)が
lのPCBに保存される
newlの情報(PC等)が
newlのPCBからロードされる
mi_switchが
カーネル内のどこから
呼ばれるか?がミソ
mi_switchの実装
/*
* The machine independent parts of context switch.
*
* Returns 1 if another LWP was actually run.
*/
int
mi_switch(lwp_t *l)
{
struct cpu_info *ci;
struct schedstate_percpu *spc;
struct lwp *newl;
int retval, oldspl;
struct bintime bt;
bool returning;
……….
/* Switch to the new LWP.. */
prevlwp = cpu_switchto(l, newl, returning);
ci = curcpu();
/*
* Switched away - we have new curlwp.
* Restore VM context and IPL.
*/
pmap_activate(l);
uvm_emap_switch(l);
pcu_switchpoint(l);
別のLWPにコンテキストスイッチする関数
/sys/kern/kern_synch.c
/*
* struct lwp *cpu_switchto(struct lwp *current, struct lwp *next)
* Switch to the specified next LWP
* Arguments:
* a0 'struct lwp *' of the LWP to switch from
* a1 'struct lwp *' of the LWP to switch to
*/
LEAF(cpu_switchto, 0)
LDGP(pv)
beq a0, 1f
/*
* do an inline savectx(), to save old context
*/
ldq a2, L_PCB(a0)
/* NOTE: ksp is stored by the swpctx */
stq s0, PCB_CONTEXT+(0 * 8)(a2) /* store s0 - s6 */
stq s1, PCB_CONTEXT+(1 * 8)(a2)
/sys/arch/alpha/alpha/locore.s
ここまでのおさらい
     ※ OSのなかではプロセスがぴょんぴょんしている
     ※ 違うプロセスに移る時にプロセスの状態を保存する
     ※ 違うプロセスから復帰する時にプロセスの状態を復元する
     ※ 保存する状態はCPUのレジスタとプロセスの情報
     ※ 保存する場所をPCBという
lazy FPU context switchのFPUとは?
Macintosh IIciよりMC68882
FPU(Floating Point Unit、浮動小数点(演算処理)装置)とは、
浮動小数点演算を専門に行う処理装置のこと。
コンピュータの周辺機器のようなアーキテクチャのものもあれば、
CPUと一体化したコプロセッサのようなアーキテクチャのものもある。
wikipediaより
※ FPUは浮動小数点専用のレジスタを持つ
※ でも、どんなプログラムもFPUを使うとは限らない…
※ コンテキストスイッチではCPUのレジスタを保存復帰する
※ FPUのレジスタはサイズがでかい、かつ数が多いので保存復帰が超重い…
lazy FPU context switchとは?
\  __  /
_ (m) _  ピコーン
   |ミ|
/ `´  \
  ( ゚∀゚)
 ノヽノ |
  < <
FPUを使うときだけFPUの内容を
コンテキストスイッチしよう!
つまり、Lazy context switchとは
プロセス切替時に FPUのレジスタを復帰させるのではなく、
プロセス切替後に FPUが使われた時点で初めて復帰させることで
FPUを使わない場合のコンテキストスイッチを軽くする技!なのです!
ΩΩΩ<な、なんだってー!?
PCUとは?
Per CPU Unit (PCU) is an interface to manage synchronization of any per-
CPU context (unit) tied to an LWP context. Typical use of PCU is for
”lazy-switch” synchronization of the FPU state.  NetBSD Kernel Developer's Manual PCU(9)
NetBSDでLazy context switchの対象となるCPU
※ Alpha FPUは1個
※ ARM FPUは1個
※ MIPS FPUは2個(FPUとDSP)
※ PowerPC FPUは2個(FPUとAltiVec/SPE)
※ FPUを無効化出来るCPU
※ 無効化状態でFPUを使おうとすると浮動小数点無効フォルトが発生するCPU
PCUを理解するためのお約束
※ すべてのLWPはFPUが無効の状態で作成される
struct lwp {
/* Scheduling and overall state. */
……….
#if PCU_UNIT_COUNT > 0
struct cpu_info * volatile l_pcu_cpu[PCU_UNIT_COUNT];
uint32_t l_pcu_valid;
#endif
………….
/sys/sys/lwp.h
struct cpu_data {
/*
* The first section is likely to be touched by other CPUs -
* it is cache hot.
*/
lwp_t *cpu_biglock_wanted; /* LWP spinning on biglock */
………..
struct lwp * volatile cpu_pcu_curlwp[PCU_UNIT_COUNT];
……….
/sys/sys/cpu_data.h
← FPUを使用している(た)
LWPのアドレス
← FPUを使用している(た)
  CPU構造体のアドレス
予習として描いてみた
exec
setreg
fpu_state_release
PCBのFPUを保存する領域
を初期化
~MDLWP_FPACTIVEで
FPU無効化フラグを立てる
exception_return FPUが使えなくなる
(*^-゚)vィェィ♪
では実装
(プロセスが作成される所まで)
execve_runproc
/sys/kern/kern_exec.c
static int
execve_runproc(struct lwp *l, struct execve_data * restrict data,
bool no_local_exec_lock, bool is_spawn)
{
struct exec_package * const epp = &data->ed_pack;
int error = 0;
struct proc *p;
……….
/*
* Set initial SP at the top of the stack.
*
* Note that on machines where stack grows up (e.g. hppa), SP points to
* the end of arg/env strings. Userland guesses the address of argc
* via ps_strings::ps_argvstr.
*/
/* Setup new registers and do misc. setup. */
(*epp->ep_esch->es_emul->e_setregs)(l, epp, (vaddr_t)newstack);
if (epp->ep_esch->es_setregs)
(*epp->ep_esch->es_setregs)(l, epp, (vaddr_t)newstack);
……….
/* Discard all PCU state; need to start fresh */
pcu_discard_all(l);
まずはPCBの初期化から
setregs
ユーザープロセスがプログラムを
実行できるようにスタックの設定、
レジスタの初期化を行う
/sys/arch/alpha/alpha/machdep.c
/*
* Set registers on exec.
*/
void
setregs(register struct lwp *l, struct exec_package *pack, vaddr_t stack)
{
struct trapframe *tfp = l->l_md.md_tf;
struct pcb *pcb;
……….
pcb = lwp_getpcb(l);
memset(&pcb->pcb_fp, 0, sizeof(pcb->pcb_fp));
alpha_pal_wrusp(stack);
tfp->tf_regs[FRAME_PS] = ALPHA_PSL_USERSET;
tfp->tf_regs[FRAME_PC] = pack->ep_entry & ~3;
tfp->tf_regs[FRAME_A0] = stack; /* a0 = sp */
tfp->tf_regs[FRAME_A1] = 0; /* a1 = rtld cleanup */
tfp->tf_regs[FRAME_A2] = 0; /* a2 = rtld object */
tfp->tf_regs[FRAME_A3] = l->l_proc->p_psstrp; /* a3 = ps_strings */
tfp->tf_regs[FRAME_T12] = tfp->tf_regs[FRAME_PC]; /* a.k.a. PV */
←PCBのFPUを保存する領域
を初期化する
execve_runproc
sys/kern/kern_exec.c
static int
execve_runproc(struct lwp *l, struct execve_data * restrict data,
bool no_local_exec_lock, bool is_spawn)
{
struct exec_package * const epp = &data->ed_pack;
int error = 0;
struct proc *p;
……….
/*
* Set initial SP at the top of the stack.
*
* Note that on machines where stack grows up (e.g. hppa), SP points to
* the end of arg/env strings. Userland guesses the address of argc
* via ps_strings::ps_argvstr.
*/
/* Setup new registers and do misc. setup. */
(*epp->ep_esch->es_emul->e_setregs)(l, epp, (vaddr_t)newstack);
if (epp->ep_esch->es_setregs)
(*epp->ep_esch->es_setregs)(l, epp, (vaddr_t)newstack);
……….
/* Discard all PCU state; need to start fresh */
pcu_discard_all(l);
次はFPUの無効化
/sys/kern/subr_pcu.c
FPUを無効化する
const pcu_ops_t fpu_ops = {
.pcu_id = PCU_FPU,
.pcu_state_load = fpu_state_load,
.pcu_state_save = fpu_state_save,
.pcu_state_release = fpu_state_release,
};
const pcu_ops_t * const pcu_ops_md_defs[PCU_UNIT_COUNT] = {
[PCU_FPU] = &fpu_ops,
};
/*
* pcu_discard_all: discard PCU state of the given LWP.
*
* Used by exec and LWP exit.
*/
void
pcu_discard_all(lwp_t *l)
{
const uint32_t pcu_valid = l->l_pcu_valid;
if (__predict_true(pcu_valid == 0)) {
/* PCUs are not in use. */
return;
}
for (u_int id = 0; id < PCU_UNIT_COUNT; id++) {
if ((pcu_valid & (1U << id)) == 0) {
continue;
}
if (__predict_true(l->l_pcu_cpu[id] == NULL)) {
continue;
}
const pcu_ops_t * const pcu = pcu_ops_md_defs[id];
pcu_lwp_op(pcu, l, PCU_CMD_RELEASE);
}
l->l_pcu_valid = 0;
}
/src/sys/arch/alpha/alpha/machdep.c
親LWPがFPUを使っていたら、
FPUを無効化するために
pcu_lwp_op()内で
pcu_ops_t構造体経由で
fpu_state_release()を呼びます
FPUを無効化する
/*
* Release the FPU.
*/
void
fpu_state_release(struct lwp *l)
{
l->l_md.md_flags &= ~MDLWP_FPACTIVE;
}
/src/sys/arch/alpha/alpha/fp_complete.c
#define MDLWP_FP_C 0x007ffffe /* Extended FP_C Quadword bits */
#define MDLWP_FPACTIVE __BIT(63) /* FPU is active on LWP's PCU CPU */
/src/sys/arch/alpha/include/proc.h
←フラグをセットします
この時点ではまだFPUは無効ではありません!
フラグをセットしただけです。
/*
* exception_return: return from trap, exception, or syscall
*/
IMPORT(ssir, 8)
LEAF(exception_return, 1) /* XXX should be NESTED */
br pv, 1f
……….
/* GET_CPUINFO clobbers v0, t0, t8...t11. */
3: GET_CPUINFO
/* check for AST */
ldq t1, CPU_INFO_CURLWP(v0)
ldl t3, L_MD_ASTPENDING(t1) /* AST pending? */
bne t3, 7f /* yes */
/* no: headed back to user space */
/* Enable the FPU based on whether MDLWP_FPACTIVE is set. */
4: ldq t2, L_MD_FLAGS(t1)
cmplt t2, zero, a0
call_pal PAL_OSF1_wrfen
FPUを無効化した状態でプロセスの作成を完了する
trap()/systemcall()を終了するときに
exception_return()でFPUを
有効化したり無効化したりします
/sys/arch/alpha/alpha/locore.s FENに1を立てるとFPUがON
次にFPUを使ってみる
……….
$main..ng:
lda $30,-64($30)
.cfi_def_cfa_offset 64
stq $26,0($30)
stq $15,8($30)
……….
stl $1,48($15)
ldah $1,$LC0($29) !gprelhigh
ldt $f10,$LC0($1) !gprellow
……….
divt/sui $f12,$f11,$f10
trapb
stt $f10,32($15)
……….
FPUが無効化された状態で
LWPが作成されました!
次はFPUを使ってみましょう!
予習として描いてみた
FPUが使えない状態でLWP作成
浮動小数点命令を発効
※ 以前にCPU(FPU)を使用していたLWPのFPUレジスタの内容を
そのLWPのPCBにセーブ/リリース
※ 自分用のPCBに保存してあるFPUのレジスタの内容をFPUにロード
※ exception_return()でFPU有効化
trap()
では実装
(FPUがロードされる所まで)
浮動小数点命令を実行すると、浮動小数点無効フォルトが発生する
/sys/arch/alpha/alpha/trap.c 浮動小数点命令を実行出来るように
fpu_load(pcu_load)を呼びます
/*
* Trap is called from locore to handle most types of processor traps.
* System calls are broken out for efficiency and ASTs are broken out
* to make the code a bit cleaner and more representative of the
* Alpha architecture.
*/
/*ARGSUSED*/
void
trap(const u_long a0, const u_long a1, const u_long a2, const u_long entry,
struct trapframe *framep)
{
struct lwp *l;
struct proc *p;
struct pcb *pcb;
……….
case ALPHA_KENTRY_IF:
/*
* These are always fatal in kernel, and should
never
* happen. (Debugger entry is handled in XentIF.)
……….
case ALPHA_IF_CODE_FEN:
fpu_load();
goto out;
static inline void
fpu_load(void)
{
pcu_load(&fpu_ops);
}
static inline void
fpu_save(void)
{
pcu_save(&fpu_ops);
}
static inline void
fpu_discard(bool valid_p)
{
pcu_discard(&fpu_ops, valid_p);
}
FPUをsave/releaseする
もし、このLWPがFPU(CPU)の
実行権限を取得する「以前」に
別のLWPがFPUを使っていたら
FPUのレジスタをセーブ、リリース
/*
* pcu_load: load/initialize the PCU state of current LWP on current CPU.
*/
void
pcu_load(const pcu_ops_t *pcu)
{
lwp_t *oncpu_lwp, * const l = curlwp;
const u_int id = pcu->pcu_id;
struct cpu_info *ci, *curci;
int s;
……….
/* Save the PCU state on the current CPU, if there is any. */
if ((oncpu_lwp = curci->ci_pcu_curlwp[id]) != NULL) {
pcu_do_op(pcu, oncpu_lwp, PCU_CMD_SAVE | PCU_CMD_RELEASE);
}
……….
/*
* Finally, load the state for this LWP on this CPU. Indicate to
* the load function whether PCU state was valid before this call.
*/
const bool valid = ((1U << id) & l->l_pcu_valid) != 0;
pcu->pcu_state_load(l, valid ? PCU_VALID : 0);
curci->ci_pcu_curlwp[id] = l;
l->l_pcu_cpu[id] = curci;
l->l_pcu_valid |= (1U << id);
splx(s);
}
/sys/kern/subr_pcu.c
FPUをsave/releaseする
/*
* pcu_do_op: save/release PCU state on the current CPU.
*
* => Must be called at IPL_PCU or from the interrupt.
*/
static inline void
pcu_do_op(const pcu_ops_t *pcu, lwp_t * const l, const int flags)
{
struct cpu_info * const ci = curcpu();
const u_int id = pcu->pcu_id;
KASSERT(l->l_pcu_cpu[id] == ci);
if (flags & PCU_CMD_SAVE) {
pcu->pcu_state_save(l);
}
if (flags & PCU_CMD_RELEASE) {
pcu->pcu_state_release(l);
ci->ci_pcu_curlwp[id] = NULL;
l->l_pcu_cpu[id] = NULL;
}
}
/sys/kern/subr_pcu.c
← save/releaseをするから
  割り込まれたくない?
    ∧ ∧___
   /(*゚ー゚) /\
 /| ̄∪∪ ̄|\/
   |  FPU |/
     ̄ ̄ ̄ ̄
  ∧ ∧
 (*゚ー゚)
 |つ ⊂
∼O‐つ
FPUを使いたいのにスイッチ以前のLWPの情報が残ってる….
FPUレジスタの内容を以前のLWPのPCBに保存しないと…
FPUのレジスタの内容だけスイッチ時に
PCBに退避されてないのねん
FPUをsaveする
/*
* Save the FPU state.
*/
void
fpu_state_save(struct lwp *l)
{
struct pcb * const pcb = lwp_getpcb(l);
alpha_pal_wrfen(1);
savefpstate(&pcb->pcb_fp);
alpha_pal_wrfen(0);
}
/*
* savefpstate: Save a process's floating point state.
*
* Arguments:
* a0 'struct fpstate *' to save into
*/
LEAF(savefpstate, 1)
LDGP(pv)
/* save all of the FP registers */
lda t1, FPREG_FPR_REGS(a0) /* get address of FP reg. save area */
stt $f0, (0 * 8)(t1) /* save first register, using hw name */
stt $f1, (1 * 8)(t1) /* etc. */
……….
/*
* Then save the FPCR; note that the necessary 'trapb's are taken
* care of on kernel entry and exit.
*/
mf_fpcr ft0
stt ft0, FPREG_FPR_CR(a0) /* store to FPCR save area */
RET
END(savefpstate)
※alpha_pal_wrfenはfpuを有効にする関数
(引数1で有効、引数0で無効)
一時的にFPUにアクセスするので有効にします
/sys/arch/alpha/alpha/fp_complete.c /sys/arch/alpha/alpha/locore.s
FPUをloadする
※ 現在のLWPのPCB領域に保存してある
FPUレジスタの内容をFPUにロード
※ CPU構造体に現在のLWPのアドレス
LWP構造体に現在のCPU構造体のアドレス
何個目のFPUを使用しているか
をセット
/*
* pcu_load: load/initialize the PCU state of current LWP on current CPU.
*/
void
pcu_load(const pcu_ops_t *pcu)
{
lwp_t *oncpu_lwp, * const l = curlwp;
const u_int id = pcu->pcu_id;
struct cpu_info *ci, *curci;
int s;
……….
/* Save the PCU state on the current CPU, if there is any. */
if ((oncpu_lwp = curci->ci_pcu_curlwp[id]) != NULL) {
pcu_do_op(pcu, oncpu_lwp, PCU_CMD_SAVE | PCU_CMD_RELEASE);
}
……….
/*
* Finally, load the state for this LWP on this CPU. Indicate to
* the load function whether PCU state was valid before this call.
*/
const bool valid = ((1U << id) & l->l_pcu_valid) != 0;
pcu->pcu_state_load(l, valid ? PCU_VALID : 0);
curci->ci_pcu_curlwp[id] = l;
l->l_pcu_cpu[id] = curci;
l->l_pcu_valid |= (1U << id);
splx(s);
}
/sys/kern/subr_pcu.c
FPUをloadする
/*
* Load the float-point context for the current lwp.
*/
void
fpu_state_load(struct lwp *l, u_int flags)
{
struct pcb * const pcb = lwp_getpcb(l);
……….
if ((flags & PCU_VALID) == 0) {
atomic_inc_ulong(&fpevent_use.ev_count);
} else {
atomic_inc_ulong(&fpevent_reuse.ev_count);
}
alpha_pal_wrfen(1);
restorefpstate(&pcb->pcb_fp);
alpha_pal_wrfen(0);
l->l_md.md_flags |= MDLWP_FPACTIVE;
}
※alpha_pal_wrfenはfpuを有効にする関数
(引数1で有効、引数0で無効)
一時的にFPUにアクセスするので有効にします
/sys/arch/alpha/alpha/fp_complete.c /sys/arch/alpha/alpha/locore.s
/*
* restorefpstate: Restore a process's floating point state.
*
* Arguments:
* a0 'struct fpstate *' to restore from
*/
LEAF(restorefpstate, 1)
LDGP(pv)
/*
* Restore the FPCR; note that the necessary 'trapb's are taken care of
* on kernel entry and exit.
*/
ldt ft0, FPREG_FPR_CR(a0) /* load from FPCR save area */
mt_fpcr ft0
/* Restore all of the FP registers. */
lda t1, FPREG_FPR_REGS(a0)/* get address of FP reg. save area */
ldt $f0, (0 * 8)(t1) /* restore first reg., using hw name */
ldt $f1, (1 * 8)(t1) /* etc. */
……….
ldt $f28, (28 * 8)(t1)
ldt $f29, (29 * 8)(t1)
ldt $f30, (30 * 8)(t1)
RET
END(restorefpstate)
ここまでのおさらい
   ※ すべてのLWPはFPUが無効の状態で作成される
   ※ FPUが無効の状態で浮動小数点命令を実行すると
浮動小数点無効フォルトが発生する
   ※ (もしコンテキストスイッチ以前のLWPがFPUを使っていたら)
FPUのレジスタをセーブ、リリースする
∧ ∧  。
(*゚ー゚) /
  | ⊃⊃
∼|   |
  U~U
では応用編へ
予習として描いてみた
FPUが使えない状態でLWP作成
浮動小数点命令を発効
※ 以前にCPU(FPU)を使用していたLWPのFPUレジスタの内容を
そのLWPのPCBにセーブ/リリース
※ 自分用のPCBに保存してあるFPUのレジスタの内容をFPUにロード
※ exception_return()でFPU有効化
mi_switch syslog
mi_switch top
浮動小数点命令を発効
浮動小数点命令
普通の命令
trap()
コンテキストスイッチ
pcu_switchpoint()
でFPU無効化マーク
コンテキストスイッチ
pcu_switchpoint()
でFPU無効化マーク
trap()
※ 以前にCPU(FPU)を使用していたLWPのFPUレジスタの内容を
そのLWPのPCBにセーブ/リリース
このタイミングでFPUを保存
CPUのコンテキストスイッチと
FPUのコンテキストスイッチが一致しない
では実装
(コンテキストスイッチされるところ)
mi_switchの実装
/*
* The machine independent parts of context switch.
*
* Returns 1 if another LWP was actually run.
*/
int
mi_switch(lwp_t *l)
{
struct cpu_info *ci;
struct schedstate_percpu *spc;
struct lwp *newl;
int retval, oldspl;
struct bintime bt;
bool returning;
……….
/* Switch to the new LWP.. */
prevlwp = cpu_switchto(l, newl, returning);
ci = curcpu();
/*
* Switched away - we have new curlwp.
* Restore VM context and IPL.
*/
pmap_activate(l);
uvm_emap_switch(l);
pcu_switchpoint(l);
/sys/kern/kern_synch.c l
newl
lの情報(PC等)が
lのPCBに保存される
newlの情報(PC等)が
newlのPCBからロードされる
mi_switchが
カーネル内のどこから
呼ばれるか?がミソ
pcu_switchpoint
/*
* pcu_switchpoint: release PCU state if the LWP is being run on another CPU.
* This routine is called on each context switch by by mi_switch().
*/
void
pcu_switchpoint(lwp_t *l)
{
const uint32_t pcu_valid = l->l_pcu_valid;
int s;
KASSERTMSG(l == curlwp, "l %p != curlwp %p", l, curlwp);
if (__predict_true(pcu_valid == 0)) {
/* PCUs are not in use. */
return;
}
s = splpcu();
for (u_int id = 0; id < PCU_UNIT_COUNT; id++) {
if ((pcu_valid & (1U << id)) == 0) {
continue;
}
struct cpu_info * const pcu_ci = l->l_pcu_cpu[id];
if (pcu_ci == NULL || pcu_ci == l->l_cpu) {
continue;
}
const pcu_ops_t * const pcu = pcu_ops_md_defs[id];
pcu->pcu_state_release(l);
}
splx(s);
}
コンテキストスイッチ以前のLWPが
FPUを使っていたら
FPU無効化フラグを立てる
trap()/systemcall()(exception_return)が呼
ばれてもFPUは有効にならない
/sys/kern/subr_pcu.c
おしまい
で、trapb命令は?
※ trapb命令を実行すると特殊なtrapが発生するが、
その処理内で無条件にfpu_load()を呼んでいた!
※ つまり、fpu_load()の二度掛けをしていた
  → それまでの演算結果の破棄….
※ trapb命令は結構面白い命令なのでどっかで発表したいです…
fpu_load()は容量用法を守って正しくお使いください
参考文献 & お世話になった方
OSの一般的な知識
BSDカーネルの設計と実装 -FreeBSD詳解-
Solarisインターナル ―カーネル構造のすべて
Lion’s Commentary on UNIX
はじめてのOSコードリーディング UNIX V6で学ぶカーネルのしくみ
Alphaについて
Alpha Architecture Reference Manual Fourth Edition
Alpha 21264 Microprocessor Hardware Reference Manual
lazy FPU context switchについて
NetBSD Documentation: How lazy FPU context switch works
http://www.netbsd.org/docs/kernel/lazyfpu.html
NetBSD ドキュメンテーション: どのように lazy FPU コンテキストスイッチは動作するのか
http://www.jp.netbsd.org/ja/docs/kernel/lazyfpu.html
夜でもアッサム
http://assam-at-night.blogspot.jp/2006/06/lazy-fpu-context-switchnetbsd.html
お世話になった方&ファボって元気づけてくれた方
Izumi Tsutsui ‫‏‬@tsutsuii
Jun Ebihara ‫‏‬@ebijun、oshimaya ‫‏‬@oshimyja、Kenji Aoyama ‫‏‬@ao_kenji、ご注文はOSvですか? @syuu1228
NONAKA Kimihiro ‫‏‬@nonakap、Hiroshi Tokuda ‫‏‬@tokudahiroshi、 伊織ん@へら ‫‏‬@ioriveur
波打際のだよもんさん ‫‏‬@daemon1995、まあぼ@cub ‫‏‬@marbocub じとめすきー @lycoris_blog
※イカ先生 @impreza_gf8さんにはAlpha Station XP1000を譲っていただきました!
※ mltermはarakiken @arakikenさんの高性能ターミナルエミュレータです! ※ mikutterはおさわり大臣@toshi_aさんの高性能ておくれtwitterクライアントです!

More Related Content

What's hot

RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析Mr. Vengineer
 
10分で分かるLinuxブロックレイヤ
10分で分かるLinuxブロックレイヤ10分で分かるLinuxブロックレイヤ
10分で分かるLinuxブロックレイヤTakashi Hoshino
 
仮想化技術によるマルウェア対策とその問題点
仮想化技術によるマルウェア対策とその問題点仮想化技術によるマルウェア対策とその問題点
仮想化技術によるマルウェア対策とその問題点Kuniyasu Suzaki
 
ARM Trusted FirmwareのBL31を単体で使う!
ARM Trusted FirmwareのBL31を単体で使う!ARM Trusted FirmwareのBL31を単体で使う!
ARM Trusted FirmwareのBL31を単体で使う!Mr. Vengineer
 
Dalvik仮想マシンのアーキテクチャ 改訂版
Dalvik仮想マシンのアーキテクチャ 改訂版Dalvik仮想マシンのアーキテクチャ 改訂版
Dalvik仮想マシンのアーキテクチャ 改訂版Takuya Matsunaga
 
Zynq mp勉強会資料
Zynq mp勉強会資料Zynq mp勉強会資料
Zynq mp勉強会資料一路 川染
 
いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例Fixstars Corporation
 
Linux MMAP & Ioremap introduction
Linux MMAP & Ioremap introductionLinux MMAP & Ioremap introduction
Linux MMAP & Ioremap introductionGene Chang
 
AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解MITSUNARI Shigeo
 
ARM LinuxのMMUはわかりにくい
ARM LinuxのMMUはわかりにくいARM LinuxのMMUはわかりにくい
ARM LinuxのMMUはわかりにくいwata2ki
 
COSCUP 2020 RISC-V 32 bit linux highmem porting
COSCUP 2020 RISC-V 32 bit linux highmem portingCOSCUP 2020 RISC-V 32 bit linux highmem porting
COSCUP 2020 RISC-V 32 bit linux highmem portingEric Lin
 
LAS16-111: Easing Access to ARM TrustZone – OP-TEE and Raspberry Pi 3
LAS16-111: Easing Access to ARM TrustZone – OP-TEE and Raspberry Pi 3LAS16-111: Easing Access to ARM TrustZone – OP-TEE and Raspberry Pi 3
LAS16-111: Easing Access to ARM TrustZone – OP-TEE and Raspberry Pi 3Linaro
 
Boosting I/O Performance with KVM io_uring
Boosting I/O Performance with KVM io_uringBoosting I/O Performance with KVM io_uring
Boosting I/O Performance with KVM io_uringShapeBlue
 
不揮発メモリ(NVDIMM)とLinuxの対応動向について(for comsys 2019 ver.)
不揮発メモリ(NVDIMM)とLinuxの対応動向について(for comsys 2019 ver.)不揮発メモリ(NVDIMM)とLinuxの対応動向について(for comsys 2019 ver.)
不揮発メモリ(NVDIMM)とLinuxの対応動向について(for comsys 2019 ver.)Yasunori Goto
 
Dave Gilbert - KVM and QEMU
Dave Gilbert - KVM and QEMUDave Gilbert - KVM and QEMU
Dave Gilbert - KVM and QEMUDanny Abukalam
 
Linux Memory Management with CMA (Contiguous Memory Allocator)
Linux Memory Management with CMA (Contiguous Memory Allocator)Linux Memory Management with CMA (Contiguous Memory Allocator)
Linux Memory Management with CMA (Contiguous Memory Allocator)Pankaj Suryawanshi
 
OPcacheの新機能ファイルベースキャッシュの内部実装を読んでみた
OPcacheの新機能ファイルベースキャッシュの内部実装を読んでみたOPcacheの新機能ファイルベースキャッシュの内部実装を読んでみた
OPcacheの新機能ファイルベースキャッシュの内部実装を読んでみたYoshio Hanawa
 
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門Norishige Fukushima
 

What's hot (20)

RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
 
10分で分かるLinuxブロックレイヤ
10分で分かるLinuxブロックレイヤ10分で分かるLinuxブロックレイヤ
10分で分かるLinuxブロックレイヤ
 
仮想化技術によるマルウェア対策とその問題点
仮想化技術によるマルウェア対策とその問題点仮想化技術によるマルウェア対策とその問題点
仮想化技術によるマルウェア対策とその問題点
 
ARM Trusted FirmwareのBL31を単体で使う!
ARM Trusted FirmwareのBL31を単体で使う!ARM Trusted FirmwareのBL31を単体で使う!
ARM Trusted FirmwareのBL31を単体で使う!
 
Dalvik仮想マシンのアーキテクチャ 改訂版
Dalvik仮想マシンのアーキテクチャ 改訂版Dalvik仮想マシンのアーキテクチャ 改訂版
Dalvik仮想マシンのアーキテクチャ 改訂版
 
Zynq mp勉強会資料
Zynq mp勉強会資料Zynq mp勉強会資料
Zynq mp勉強会資料
 
いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例
 
C++ マルチスレッド 入門
C++ マルチスレッド 入門C++ マルチスレッド 入門
C++ マルチスレッド 入門
 
Linux MMAP & Ioremap introduction
Linux MMAP & Ioremap introductionLinux MMAP & Ioremap introduction
Linux MMAP & Ioremap introduction
 
AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解
 
ARM LinuxのMMUはわかりにくい
ARM LinuxのMMUはわかりにくいARM LinuxのMMUはわかりにくい
ARM LinuxのMMUはわかりにくい
 
COSCUP 2020 RISC-V 32 bit linux highmem porting
COSCUP 2020 RISC-V 32 bit linux highmem portingCOSCUP 2020 RISC-V 32 bit linux highmem porting
COSCUP 2020 RISC-V 32 bit linux highmem porting
 
LAS16-111: Easing Access to ARM TrustZone – OP-TEE and Raspberry Pi 3
LAS16-111: Easing Access to ARM TrustZone – OP-TEE and Raspberry Pi 3LAS16-111: Easing Access to ARM TrustZone – OP-TEE and Raspberry Pi 3
LAS16-111: Easing Access to ARM TrustZone – OP-TEE and Raspberry Pi 3
 
Boosting I/O Performance with KVM io_uring
Boosting I/O Performance with KVM io_uringBoosting I/O Performance with KVM io_uring
Boosting I/O Performance with KVM io_uring
 
不揮発メモリ(NVDIMM)とLinuxの対応動向について(for comsys 2019 ver.)
不揮発メモリ(NVDIMM)とLinuxの対応動向について(for comsys 2019 ver.)不揮発メモリ(NVDIMM)とLinuxの対応動向について(for comsys 2019 ver.)
不揮発メモリ(NVDIMM)とLinuxの対応動向について(for comsys 2019 ver.)
 
Microkernel Evolution
Microkernel EvolutionMicrokernel Evolution
Microkernel Evolution
 
Dave Gilbert - KVM and QEMU
Dave Gilbert - KVM and QEMUDave Gilbert - KVM and QEMU
Dave Gilbert - KVM and QEMU
 
Linux Memory Management with CMA (Contiguous Memory Allocator)
Linux Memory Management with CMA (Contiguous Memory Allocator)Linux Memory Management with CMA (Contiguous Memory Allocator)
Linux Memory Management with CMA (Contiguous Memory Allocator)
 
OPcacheの新機能ファイルベースキャッシュの内部実装を読んでみた
OPcacheの新機能ファイルベースキャッシュの内部実装を読んでみたOPcacheの新機能ファイルベースキャッシュの内部実装を読んでみた
OPcacheの新機能ファイルベースキャッシュの内部実装を読んでみた
 
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門
 

Viewers also liked

Redisへと至る、gumiデータストアの歴史
Redisへと至る、gumiデータストアの歴史Redisへと至る、gumiデータストアの歴史
Redisへと至る、gumiデータストアの歴史知教 本間
 
並列プログラミング 入門!&おさらい!
並列プログラミング入門!&おさらい!並列プログラミング入門!&おさらい!
並列プログラミング 入門!&おさらい!道化師 堂華
 
Redis & Redis HA design with Keepalived
Redis & Redis HA design with KeepalivedRedis & Redis HA design with Keepalived
Redis & Redis HA design with KeepalivedToshiki Inami
 
ソーシャルアプリにおけるRedisの活用事例とトラブル事例
ソーシャルアプリにおけるRedisの活用事例とトラブル事例ソーシャルアプリにおけるRedisの活用事例とトラブル事例
ソーシャルアプリにおけるRedisの活用事例とトラブル事例leverages_event
 
Performance Tuning EC2 Instances
Performance Tuning EC2 InstancesPerformance Tuning EC2 Instances
Performance Tuning EC2 InstancesBrendan Gregg
 
Nginx勉強会
Nginx勉強会Nginx勉強会
Nginx勉強会Yuji Otani
 

Viewers also liked (7)

Redisへと至る、gumiデータストアの歴史
Redisへと至る、gumiデータストアの歴史Redisへと至る、gumiデータストアの歴史
Redisへと至る、gumiデータストアの歴史
 
並列プログラミング 入門!&おさらい!
並列プログラミング入門!&おさらい!並列プログラミング入門!&おさらい!
並列プログラミング 入門!&おさらい!
 
Redis & Redis HA design with Keepalived
Redis & Redis HA design with KeepalivedRedis & Redis HA design with Keepalived
Redis & Redis HA design with Keepalived
 
ソーシャルアプリにおけるRedisの活用事例とトラブル事例
ソーシャルアプリにおけるRedisの活用事例とトラブル事例ソーシャルアプリにおけるRedisの活用事例とトラブル事例
ソーシャルアプリにおけるRedisの活用事例とトラブル事例
 
nginxの紹介
nginxの紹介nginxの紹介
nginxの紹介
 
Performance Tuning EC2 Instances
Performance Tuning EC2 InstancesPerformance Tuning EC2 Instances
Performance Tuning EC2 Instances
 
Nginx勉強会
Nginx勉強会Nginx勉強会
Nginx勉強会
 

Similar to あるコンテキストスイッチの話

リアルタイムOsのカスタマイズ
リアルタイムOsのカスタマイズリアルタイムOsのカスタマイズ
リアルタイムOsのカスタマイズKazuhiro Takahashi
 
LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介MITSUNARI Shigeo
 
2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめMakiko Konoshima
 
OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1
OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1
OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1Etsuji Nakai
 
ちょっと古いマシンにLinuxを
ちょっと古いマシンにLinuxをちょっと古いマシンにLinuxを
ちょっと古いマシンにLinuxをKenichiro MATOHARA
 
CCMSI計算科学技術特論A (2015) 第7回 線形代数演算ライブラリBLASとLAPACKの基礎と実践2
CCMSI計算科学技術特論A (2015) 第7回 線形代数演算ライブラリBLASとLAPACKの基礎と実践2CCMSI計算科学技術特論A (2015) 第7回 線形代数演算ライブラリBLASとLAPACKの基礎と実践2
CCMSI計算科学技術特論A (2015) 第7回 線形代数演算ライブラリBLASとLAPACKの基礎と実践2Computational Materials Science Initiative
 
2015年度GPGPU実践基礎工学 第8回 並列計算の概念 (プロセスとスレッド)
2015年度GPGPU実践基礎工学 第8回 並列計算の概念(プロセスとスレッド)2015年度GPGPU実践基礎工学 第8回 並列計算の概念(プロセスとスレッド)
2015年度GPGPU実践基礎工学 第8回 並列計算の概念 (プロセスとスレッド)智啓 出川
 
【旧版】2009/12/10 GPUコンピューティングの現状とスーパーコンピューティングの未来
【旧版】2009/12/10 GPUコンピューティングの現状とスーパーコンピューティングの未来【旧版】2009/12/10 GPUコンピューティングの現状とスーパーコンピューティングの未来
【旧版】2009/12/10 GPUコンピューティングの現状とスーパーコンピューティングの未来Preferred Networks
 
PHPとシグナル、その裏側
PHPとシグナル、その裏側PHPとシグナル、その裏側
PHPとシグナル、その裏側do_aki
 
【学習メモ#8th】12ステップで作る組込みOS自作入門
【学習メモ#8th】12ステップで作る組込みOS自作入門 【学習メモ#8th】12ステップで作る組込みOS自作入門
【学習メモ#8th】12ステップで作る組込みOS自作入門 sandai
 
Lagopus as open flow hybrid switch 実践編
Lagopus as open flow hybrid switch 実践編Lagopus as open flow hybrid switch 実践編
Lagopus as open flow hybrid switch 実践編Masaru Oki
 
高速ネットワーク最新動向と具体例 (ENOG58 Meeting)
高速ネットワーク最新動向と具体例 (ENOG58 Meeting)高速ネットワーク最新動向と具体例 (ENOG58 Meeting)
高速ネットワーク最新動向と具体例 (ENOG58 Meeting)Naoto MATSUMOTO
 
Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Ransui Iso
 
[D12] NonStop SQLって何? by Susumu Yamamoto
[D12] NonStop SQLって何? by Susumu Yamamoto[D12] NonStop SQLって何? by Susumu Yamamoto
[D12] NonStop SQLって何? by Susumu YamamotoInsight Technology, Inc.
 
最近の身の回りの電力事情
最近の身の回りの電力事情最近の身の回りの電力事情
最近の身の回りの電力事情Kenichiro MATOHARA
 

Similar to あるコンテキストスイッチの話 (20)

リアルタイムOsのカスタマイズ
リアルタイムOsのカスタマイズリアルタイムOsのカスタマイズ
リアルタイムOsのカスタマイズ
 
LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介
 
2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ
 
OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1
OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1
OpenStackクラウド基盤構築ハンズオンセミナー 第1日:ハンズオンNo1
 
Opnfv handson apex intro
Opnfv handson apex introOpnfv handson apex intro
Opnfv handson apex intro
 
ちょっと古いマシンにLinuxを
ちょっと古いマシンにLinuxをちょっと古いマシンにLinuxを
ちょっと古いマシンにLinuxを
 
CCMSI計算科学技術特論A (2015) 第7回 線形代数演算ライブラリBLASとLAPACKの基礎と実践2
CCMSI計算科学技術特論A (2015) 第7回 線形代数演算ライブラリBLASとLAPACKの基礎と実践2CCMSI計算科学技術特論A (2015) 第7回 線形代数演算ライブラリBLASとLAPACKの基礎と実践2
CCMSI計算科学技術特論A (2015) 第7回 線形代数演算ライブラリBLASとLAPACKの基礎と実践2
 
Minix smp
Minix smpMinix smp
Minix smp
 
What is Metasepi?
What is Metasepi?What is Metasepi?
What is Metasepi?
 
2015年度GPGPU実践基礎工学 第8回 並列計算の概念 (プロセスとスレッド)
2015年度GPGPU実践基礎工学 第8回 並列計算の概念(プロセスとスレッド)2015年度GPGPU実践基礎工学 第8回 並列計算の概念(プロセスとスレッド)
2015年度GPGPU実践基礎工学 第8回 並列計算の概念 (プロセスとスレッド)
 
【旧版】2009/12/10 GPUコンピューティングの現状とスーパーコンピューティングの未来
【旧版】2009/12/10 GPUコンピューティングの現状とスーパーコンピューティングの未来【旧版】2009/12/10 GPUコンピューティングの現状とスーパーコンピューティングの未来
【旧版】2009/12/10 GPUコンピューティングの現状とスーパーコンピューティングの未来
 
不揮発WALバッファ
不揮発WALバッファ不揮発WALバッファ
不揮発WALバッファ
 
PHPとシグナル、その裏側
PHPとシグナル、その裏側PHPとシグナル、その裏側
PHPとシグナル、その裏側
 
Altanative macro
Altanative macroAltanative macro
Altanative macro
 
【学習メモ#8th】12ステップで作る組込みOS自作入門
【学習メモ#8th】12ステップで作る組込みOS自作入門 【学習メモ#8th】12ステップで作る組込みOS自作入門
【学習メモ#8th】12ステップで作る組込みOS自作入門
 
Lagopus as open flow hybrid switch 実践編
Lagopus as open flow hybrid switch 実践編Lagopus as open flow hybrid switch 実践編
Lagopus as open flow hybrid switch 実践編
 
高速ネットワーク最新動向と具体例 (ENOG58 Meeting)
高速ネットワーク最新動向と具体例 (ENOG58 Meeting)高速ネットワーク最新動向と具体例 (ENOG58 Meeting)
高速ネットワーク最新動向と具体例 (ENOG58 Meeting)
 
Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6
 
[D12] NonStop SQLって何? by Susumu Yamamoto
[D12] NonStop SQLって何? by Susumu Yamamoto[D12] NonStop SQLって何? by Susumu Yamamoto
[D12] NonStop SQLって何? by Susumu Yamamoto
 
最近の身の回りの電力事情
最近の身の回りの電力事情最近の身の回りの電力事情
最近の身の回りの電力事情
 

More from nullnilaki

あるブートローダの話
あるブートローダの話あるブートローダの話
あるブートローダの話nullnilaki
 
最後の楽園の開発をちょこっとだけ手伝った話
最後の楽園の開発をちょこっとだけ手伝った話最後の楽園の開発をちょこっとだけ手伝った話
最後の楽園の開発をちょこっとだけ手伝った話nullnilaki
 
あるキャッシュメモリの話
あるキャッシュメモリの話あるキャッシュメモリの話
あるキャッシュメモリの話nullnilaki
 
オープンソース開発と、 あるフレームバッファコンソールの話 ~名古屋応用編~
オープンソース開発と、あるフレームバッファコンソールの話~名古屋応用編~オープンソース開発と、あるフレームバッファコンソールの話~名古屋応用編~
オープンソース開発と、 あるフレームバッファコンソールの話 ~名古屋応用編~nullnilaki
 
あるクリスマスの話
あるクリスマスの話あるクリスマスの話
あるクリスマスの話nullnilaki
 
あるmmapの話
あるmmapの話あるmmapの話
あるmmapの話nullnilaki
 
DEC_6600,DEC_TITAN Implementation of NetBSD(仮)
 DEC_6600,DEC_TITAN Implementation of NetBSD(仮) DEC_6600,DEC_TITAN Implementation of NetBSD(仮)
DEC_6600,DEC_TITAN Implementation of NetBSD(仮)nullnilaki
 

More from nullnilaki (7)

あるブートローダの話
あるブートローダの話あるブートローダの話
あるブートローダの話
 
最後の楽園の開発をちょこっとだけ手伝った話
最後の楽園の開発をちょこっとだけ手伝った話最後の楽園の開発をちょこっとだけ手伝った話
最後の楽園の開発をちょこっとだけ手伝った話
 
あるキャッシュメモリの話
あるキャッシュメモリの話あるキャッシュメモリの話
あるキャッシュメモリの話
 
オープンソース開発と、 あるフレームバッファコンソールの話 ~名古屋応用編~
オープンソース開発と、あるフレームバッファコンソールの話~名古屋応用編~オープンソース開発と、あるフレームバッファコンソールの話~名古屋応用編~
オープンソース開発と、 あるフレームバッファコンソールの話 ~名古屋応用編~
 
あるクリスマスの話
あるクリスマスの話あるクリスマスの話
あるクリスマスの話
 
あるmmapの話
あるmmapの話あるmmapの話
あるmmapの話
 
DEC_6600,DEC_TITAN Implementation of NetBSD(仮)
 DEC_6600,DEC_TITAN Implementation of NetBSD(仮) DEC_6600,DEC_TITAN Implementation of NetBSD(仮)
DEC_6600,DEC_TITAN Implementation of NetBSD(仮)
 

Recently uploaded

【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 

Recently uploaded (9)

【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 

あるコンテキストスイッチの話