やってみた(追記&書き直し)
1.TLBのキャッシュにヒットするreadのコスト
2.invlpgでキャッシュをクリアするコスト
3.invlpgでTLBのキャッシュを無効にしてからread
4.以前と同じループ
計測結果および詳細はこちら(http://mona.sourceforge.jp/dynamic/pukiwiki/pukiwiki/pukiwiki.php?%B5%C4%CF%C0%2F%A5%E1%A5%C3%A5%BB%A1%BC%A5%B8%2FCR3%C0%DA%C2%D8%A5%B3%A5%B9%A5%C8)
disableInterrupt(); dword total; int count; total = 0; count = 0; for (int i = 0; i < 500; i++) { /* at first flush all */ g_page_manager->setPageDirectory(cr31); g_page_manager->setPageDirectory(cr32); dword l1, l2, h1, h2; dword* p = (dword*)0x600000; /* read and create cache */ volatile dword test1 = *p; rdtsc(&l1, &h1); /* read once using cache */ volatile dword test2 = *p; rdtsc(&l2, &h2); if (h1 != h2) continue; count++; total += (l2 - l1); } g_console->printf("read using cache: %d\n", total / count); total = 0; count = 0; for (int i = 0; i < 500; i++) { /* at first flush all */ g_page_manager->setPageDirectory(cr31); g_page_manager->setPageDirectory(cr32); dword l1, l2, h1, h2; dword* p = (dword*)0x600000; /* read and create cache */ volatile dword test1 = *p; rdtsc(&l1, &h1); asm volatile ("invlpg %0\n": "=m"(p)); rdtsc(&l2, &h2); if (h1 != h2) continue; count++; total += (l2 - l1); } g_console->printf("invlpg: %d\n", total / count); total = 0; count = 0; for (int i = 0; i < 500; i++) { /* at first flush all */ g_page_manager->setPageDirectory(cr31); g_page_manager->setPageDirectory(cr32); dword l1, l2, h1, h2; dword* p = (dword*)0x600000; /* read and create cache */ volatile dword test1 = *p; asm volatile ("invlpg %0\n": "=m"(p)); rdtsc(&l1, &h1); /* read once */ volatile dword test2 = *p; rdtsc(&l2, &h2); if (h1 != h2) continue; count++; total += (l2 - l1); } g_console->printf("create cache and read: %d\n", total / count); total = 0; count = 0; for (int i = 0; i < 500; i++) { /* at first flush all */ g_page_manager->setPageDirectory(cr31); g_page_manager->setPageDirectory(cr32); dword l1, l2, h1, h2; dword* p = (dword*)0x600000; /* read and create cache */ volatile dword test1 = *p; rdtsc(&l1, &h1); for (int j = 0; j < 10000; j++) { j++; j--; } rdtsc(&l2, &h2); if (h1 != h2) continue; count++; total += (l2 - l1); } g_console->printf("loop: %d\n", total / count);