c言語でmallocが使えない環境(fpgaへの実装を想定、固定長配列で実装)で簡単なキャッシュを作ろうとしています。
C
1//main.c 2#include <stdlib.h> 3#include <stdio.h> 4 5#define TIMEOUT_SECOND 2 6 7#define MAXOBJ 16 8#define BUF_SIZE 10 9#define BUF_LENGTH 100 10#define INVALID_LENGTH 7 11 12int cache(char recvBuffer[BUF_LENGTH]); 13 14int intTries = 0; 15int main(int argc, char *argv[]) { 16 17 char recvBuffer1[MAX_BUFSIZE] = "bbtest"; 18 19 for (int i = 0; i < 10; ++i) { 20 int result1 = cache(recvBuffer1); 21 //int result2 = cache(recvBuffer2); 22 23 printf("result1 is : %d\n", result1); 24 25 } 26 return 0; 27} 28
C
1//cache.c 2#include <stdlib.h> 3#include <stdio.h> 4#include <time.h> 5#include <assert.h> 6 7#define MSG_FAILURE -1 8#define MAX_MSGSIZE 100 9#define MAX_BUFSIZE (MAX_MSGSIZE + 1) 10#define MAX_TRIES 5 11#define TIMEOUT_SECOND 2 12#define ARRAY_SIZE 100 13 14#define MAXOBJ 16 15#define BUF_SIZE 10 16#define BUF_LENGTH 100 17#define INVALID_LENGTH 7 18 19 20int cache(char *recvBuffer){ 21 22 //cache definition-------------------------------------------------- 23 static char *cache[BUF_SIZE]; 24 char invalid[8] = "invalid"; 25 26 static char buffer1[BUF_LENGTH] = "invalid"; 27 cache[0] = &buffer1[0]; 28 static char buffer2[BUF_LENGTH] = "invalid"; 29 cache[1] = &buffer2[0]; 30 static char buffer3[BUF_LENGTH] = "invalid"; 31 cache[2] = &buffer3[0]; 32 static char buffer4[BUF_LENGTH] = "invalid"; 33 cache[3] = &buffer4[0]; 34 static char buffer5[BUF_LENGTH] = "invalid"; 35 cache[4] = &buffer5[0]; 36 static char buffer6[BUF_LENGTH] = "invalid"; 37 cache[5] = &buffer6[0]; 38 static char buffer7[BUF_LENGTH] = "invalid"; 39 cache[6] = &buffer7[0]; 40 static char buffer8[BUF_LENGTH] = "invalid"; 41 cache[7] = &buffer8[0]; 42 static char buffer9[BUF_LENGTH] = "invalid"; 43 cache[8] = &buffer9[0]; 44 static char buffer10[BUF_LENGTH] = "invalid"; 45 cache[9] = &buffer10[0]; 46 47 //print cache----------------------------------------------------- 48 49 for (int b = 0; b < BUF_SIZE; b++) { 50 printf("Cache[%d]: ", b); 51 for (int j = 0; j <INVALID_LENGTH ; ++j) { 52 printf("%c", *(cache[b] + j)); 53 } 54 printf("\n"); 55 } 56 printf("\n-------------------------------\n"); 57 58 //ここでPutかGetかを判別する。 59 if ( *(uint16_t *)recvBuffer == 0x6262){//Put 0x6262==bb 60 61 //空いている場所を探す 62 printf("Putが実行\n"); 63 printf("recvBuffer is: %s\n", recvBuffer); 64 int flag = 1; 65 for (int d = 0; d < BUF_SIZE; d++) { 66 //cache[d]がinvalidか照合 67 for (int j = 0; j < INVALID_LENGTH; j++) { 68 if (*(cache[d] + j) != invalid[j]){ 69 flag = 0;//cache[d]は空いている 70 printf("Cache[%d]の%cは%cと一致していない\n", d, *(cache[d]+j), invalid[j]); 71 } 72 } 73 //cache[d]がinvalidのとき→現状、1つでも一致すればよくなってしまっている 74 if (flag == 1) { 75 printf("Cache[%d]はinvalid!!\n", d); 76 cache[d] = recvBuffer; //[0]にはflagが入っているため 77 //無事キャッシュに格納完了 78 break; 79 } 80 } 81 //キャッシュが満杯の時、古いのを捨てる 82 if (flag == 0) { 83 printf("cache full----------------------------------\n"); 84 cache[8] = recvBuffer; //適当に8番目を入れ替える 85 } 86 // 87 //キャッシュの中身を表示 88 printf("\n-------------------------------\n"); 89 printf("new Cache is : \n"); 90 for (int c = 0; c < BUF_SIZE; c++) { 91 printf("Cache[%d]: ", c); 92 for (int j = 0; j < INVALID_LENGTH; ++j) { 93 printf("%c", *(cache[c] + j)); 94 } 95 printf("\n"); 96 } 97 return 0;//Putなので返すものはない 98 //------------------------------------- 99 } else if(*(uint16_t *)recvBuffer == 0x6161){ //Getのとき 0x6161==aa 100 printf("Getが実行\n"); 101 for (int i = 0; i < BUF_SIZE; i++) { 102 if (recvBuffer[i+1] == *cache[i]) { 103 printf("Cache Hit!"); 104 return 1; //Cache hitのときは1を返すようにする 105 break; 106 //sendBuffer_fromserver[0] = '1'; 107 } 108 } 109 //for文が最後まで実装されたらキャッシュミス 110 printf("Cache Miss!\n"); 111 return 2; //cache miss のときは2を返すようにする 112 } 113}
上のプログラムを取り敢えず作成したのですが、main中で「cache」を呼び出すとそのたびに
C
1char *cache[BUF_SIZE];
をしてしまうのでやはり毎回初期化されてしまっています。
main中でcache[BUF_SIZE]をしたいのですが、いろいろ試行錯誤してもうまくいきませんでした。。
どなたか解決策を思いつく方ご教授頂けると幸いです。
現在の進捗
C
1char *cache[BUF_SIZE];
を
C
1static char *cache[BUF_SIZE];
に修正。
C
1for (int a = 0; a < BUF_SIZE; a++) { 2char buffer[BUF_LENGTH] = "invalid"; 3cache[a] = &buffer[0]; 4}
を
C
1static char *cache[BUF_SIZE]; 2 char invalid[8] = "invalid"; 3 4 static char buffer1[BUF_LENGTH] = "invalid"; 5 cache[0] = &buffer1[0]; 6 static char buffer2[BUF_LENGTH] = "invalid"; 7 cache[1] = &buffer2[0]; 8 static char buffer3[BUF_LENGTH] = "invalid"; 9 cache[2] = &buffer3[0]; 10 static char buffer4[BUF_LENGTH] = "invalid"; 11 cache[3] = &buffer4[0]; 12 static char buffer5[BUF_LENGTH] = "invalid"; 13 cache[4] = &buffer5[0]; 14 static char buffer6[BUF_LENGTH] = "invalid"; 15 cache[5] = &buffer6[0]; 16 static char buffer7[BUF_LENGTH] = "invalid"; 17 cache[6] = &buffer7[0]; 18 static char buffer8[BUF_LENGTH] = "invalid"; 19 cache[7] = &buffer8[0]; 20 static char buffer9[BUF_LENGTH] = "invalid"; 21 cache[8] = &buffer9[0]; 22 static char buffer10[BUF_LENGTH] = "invalid"; 23 cache[9] = &buffer10[0];
に書き下し。
どういう動きをさせようとしているのか, コーディングが合っているのか間違っているのかが不明な個所が多く, 読み取れません. どのような仕様でしょうか.
パラメータのポインタを直値と比較していますが, FPGA に入れないと単体テストも出来ないということでしょうか.
ご回答ありがとうございます。情報不足の質問となってしまっており申し訳ありません。
FPGAに入れないと単体テストが出来ないわけではなく、現段階ではキャッシュ部分のみの実装をしております。
仕様といたしましては、[BUF_SIZE]個を保持するキャッシュで、それぞれサイズ[BUF_LENGTH]の文字列を格納するものを作りたいです。
現在、main中ではキャッシュに文字列を挿入する際しか実装していませんが、
キャッシュに文字列を挿入する際には0を返し、
ある文字列と同じ文字列がキャッシュ中に存在していれば1を返す、
なければ0を返すようにしています。
キャッシュへの挿入/キャッシュ中に存在するかの確認は文字列の最初の2文字(aaかbbか)で判別するようにしています。
お手数おかけしますがどうぞよろしくお願いいたします。
> 文字列の最初の2文字(aaかbbか)で判別
失礼しました, ポインタと直値の比較に見えたのは文字列だったのですね. 勘違いでした.
ところで, ヒットしたかを返すのはともかく, 挿入か確認かでデータを変えるという仕様はあるのでしょうか.
キャッシュというと, 有るかを確認し, 有ればそれを返し, 無ければ挿入した上でそれを返す…というイメージなのですが.
回答4件
あなたの回答
tips
プレビュー