https://qiita.com/hidenorly/items/4c3ce6afddd1eb908736
を参考にして,MAiX Bit等のプロセッサであるCanaan Inc.のKENDRYTE K210のCプログラミングSDKを使えるようになりました.感謝
いつものふるいで素数を求めるプログラムから初めて,マニュアル「K210 Standalone SDK Programming guide」をCanaanのページ
https://www.canaan.io/developer
からみつけて,これを見ながら,いつものキャッシュ速度測定プログラムでキャッシュのサイズを測ってみました.いつもは
getrusage(RUSAGE_SELF, &ru_before);
測るコード
getrusage(RUSAGE_SELF, &ru_after);
tb = ru_before.ru_utime.tv_usec + ru_before.ru_utime.tv_sec * 1000000;
ta = ru_after.ru_utime.tv_usec + ru_after.ru_utime.tv_sec * 1000000;
printf("%d,%d \n", i, ta - tb);
とやって,プロセスのリソース情報を取得して測っていたのだけど裸のプロセッサにそんなものあるわけないじゃーん(デジモンのあのセリフのノリ)ということで,1mSのインターバルタイマーを作って,mS精度のタイマーで測ってみました.結果は以下の通り:
256,1427
512,1380
1024,1357
2048,1345
4096,1340
8192,1337
16384,1335
32768,1367
65536,6887
131072,9319
262144,10559
524288,11113
1048576,11396
2097152,11543
どうやら32KiBのキャッシュがついているようで,メモリとの速度比は8〜9倍というところです.
以下がコードです.ヒープをランダムウオークする部分とか,K210のタイマーを使ってインターバルタイマーを作る部分とか取れるパーツは再利用してください.
/* Copyleft 2020 Gian
*/
#include <bsp.h>
#include <sysctl.h>
#include <timer.h>
#include <plic.h>
#include <stdio.h>
#include <malloc.h>
#define TD TIMER_DEVICE_0
#define TC TIMER_CHANNEL_0
volatile unsigned timer_count = 0;
timer_callback_t timer_svc() {
timer_count++;
}
char **buff = NULL;
unsigned bsize;
unsigned bmask;
unsigned repeat;
volatile unsigned tb, ta;
int zzz = 0;
#define LOAD 0x8000000
void mkbuff(unsigned size)
{
int i;
int l, m;
char **j, **k;
unsigned mm;
if (buff != NULL) free(buff);
if ((buff = (char **)malloc(size + sizeof(char *))) == NULL) {
fprintf(stderr, "MALLOC\n");
exit(-1);
}
bsize = size / sizeof(unsigned *);
repeat = LOAD / bsize;
bmask = 0xffffffff - bsize;
for (mm = 0x80000000; (mm & bsize) == 0; mm >>= 1) {
bmask -= mm;
}
for (m = -1, l = bmask; l >= 0; m++) {
l = l << 1;
}
for (i = 0; i < bsize - 1; i++) buff[i] = NULL;
k = &buff[0];
for (i = 0; i < bsize; i++) {
do {
j = &buff[(rand() >> m) & bmask];
} while (*j != NULL);
*k = j;
k = j;
}
*k = &buff[0];
}
void rtest()
{
int i, j, k;
for (i = 0; i < repeat; i++) {
for (j = 0; j < bsize; j++) {
}
}
}
int test()
{
int i, j;
char **k;
int s = 0;
k = buff[0];
for (i = 0; i < repeat; i++) {
for (j = 0; j < bsize; j++) {
k = *k;
s += (int) k;
}
}
return s;
}
int main(void)
{
unsigned i;
sysctl_pll_set_freq(SYSCTL_PLL0, 800000000);
plic_init();
timer_init(TD);
timer_set_interval(TD, TC, 1000000);
timer_irq_register(TD, TC, 0, 5, timer_svc, NULL);
timer_set_enable(TD, TC, 1);
sysctl_enable_irq();
for (i = 256; i < 0x400000; i <<= 1) {
mkbuff(i);
tb = timer_count;
zzz += test();
ta = timer_count;
printf("%d,%d \n", i, ta - tb);
}
while(1) {
}
return 0;
}