ふるた技工所(てっこうしょ)

ふるた技工所(てっこうしょ)

PR

キーワードサーチ

▼キーワード検索

プロフィール

Aちゃん22

Aちゃん22

フリーページ

2020.07.02
XML
カテゴリ: ソフト開発日誌
Linux の Userland で cache flush をしたくなったので、x86/x86-64 アーキテクチャ上で cache flush 関数を実装してみる。 Linux kernel 内に有った実装 をほぼそのまま持ってくる。
#include <stdint.h>
static void clflush(volatile void *p)
{
  asm volatile("clflush %0" : "+m"(*(volatile uint8_t *)p));
}
clflush ソース

kernel から持ってきた理由は、検索をしていたら cacheflush() system call が見つかったからだ。kernel source を調べてみると x86/x86-64 アーキテクチャではこの system call は無い様に見える。

特権を持っていなくても、CLFLUSH 命令は使えるからだろう。

試しに使ってみるコードを実装する。

#include <stdint.h>
#include <stdio.h>
#include <string.h>

static void clflush(volatile void *p)
{
  asm volatile("clflush %0" : "+m"(*(volatile uint8_t *)p));
}

const char hello[] = "Hello world.\n";

void MainB(char *buf)
{
  memcpy(buf, hello, sizeof(hello));
  clflush(buf);
  fputs(buf, stdout);
}

int main(int argc, char **argv, char **env)
{ char buf[128];
  MainB(buf);
  return 0;
}
clflush テストコード全体

逆アセンブル してみる。まぁ、まぁ、綺麗に inline でオブジェクトコードが生成されていた。

0000000000400620 <MainB>:
  400620: 48 b8 48 65 6c 6c 6f movabs $0x6f77206f6c6c6548,%rax
  400627: 20 77 6f 
  40062a: c7 47 08 72 6c 64 2e movl   $0x2e646c72,0x8(%rdi)
  400631: 48 89 07             mov    %rax,(%rdi)
  400634: b8 0a 00 00 00       mov    $0xa,%eax
  400639: 66 89 47 0c          mov    %ax,0xc(%rdi)
  40063d: 0f ae 3f             clflush (%rdi)
  400640: 48 8b 35 09 0a 20 00 mov    0x200a09(%rip),%rsi        # 601050 <stdout@@GLIBC_2.2.5>
  400647: e9 74 fe ff ff       jmpq   4004c0 <fputs@plt>
  40064c: 0f 1f 40 00          nopl   0x0(%rax)
より良い使い方は、前後に memory barrier を使う。

cache line size も /proc/cpuinfo から拾わないと。
clflush size    : 64
cache_alignment : 64





お気に入りの記事を「いいね!」で応援しよう

最終更新日  2020.07.02 22:40:13
コメント(0) | コメントを書く


【毎日開催】
15記事にいいね!で1ポイント
10秒滞在
いいね! -- / --
おめでとうございます!
ミッションを達成しました。
※「ポイントを獲得する」ボタンを押すと広告が表示されます。
x

© Rakuten Group, Inc.
Create a Mobile Website
スマートフォン版を閲覧 | PC版を閲覧
Share by: