junjunnさんのファイルシステム高速化をとりこもう
現在の trunk と junjunnさんのファイルシステムコードの diff をとって差分を把握してからとりこみたい。
ただ単純に diff をとったのでは大量の変更(数千行)が検出されてしまいうれしくない。
問題点は
- 文字コード/改行コードが変わっている
- →手動であわせた
- 最新のtrunk で取り入れた、byte -> uint8_t の変更が反映されていない
- →置換した
- ファイルシステム周りのインスタンス変数の名前の多くがリネームされている(例えば vmanager_ → m_pVnodeManager)。これがdiffとして検知されると本当の変更部分が見えづらくなってしまう。
- →がんばってリネームしなおした
取り込み
取り込みの前に、file_server_on_linux でテストが通るか、valgrind でリークチェックが必要。
valgrind でエラーが出たので、修正。
今回はウェイトとして入れていた sleep がボトルネックになっていたのだけど、これをなくすのであれば実機での検証が必要。
ただ手元の2個の実機では、Eltorito 周りでエラーになっているっぽくて検証できず。
勢いで commit してしまった。
感想
diff を見ると意外に少ないと思う人もいるかもしれないのだけど、ボトルネックを見つけるまでに、いろいろ試行錯誤した後が多数見られてかなりすごいです。
チューニングに楽な道はなくて
- ボトルネックになっている場所の特定
- 仮説
- 実験
を繰り返す、堅実な作業が必要なのだなと再確認。
junjunnさんは高速化を実現したという結果と、その過程の両方ですげーな思いました。
diff
Index: ISO9660/ISO9660FileSystem.cpp =================================================================== --- ISO9660/ISO9660FileSystem.cpp (リビジョン 3961) +++ ISO9660/ISO9660FileSystem.cpp (リビジョン 3962) @@ -96,13 +96,14 @@ int sectorCount = (offset + readSize + SECTOR_SIZE - 1) / SECTOR_SIZE - offset / SECTOR_SIZE; uint32_t sectorSize = sectorCount * SECTOR_SIZE; - uint8_t* temp = new uint8_t[sectorSize]; +#if 0 + byte* temp = new byte[sectorSize]; if (temp == NULL) return MONA_FAILURE; bool readResult = drive_->read(lba, temp, sectorSize) == 0; if (!readResult) { - delete temp; + delete[] temp; return MONA_FAILURE; } @@ -117,6 +118,45 @@ delete[] temp; context->resultSize = readSize; return MONA_SUCCESS; +#else + int dataOffset = offset - (lba - fileEntry->attribute.extent) * SECTOR_SIZE; + + context->memory = monapi_cmemoryinfo_new(); + if (!monapi_cmemoryinfo_create(context->memory, readSize, MONAPI_FALSE)) + { + monapi_cmemoryinfo_delete(context->memory); + return MONA_ERROR_MEMORY_NOT_ENOUGH; + } + + // by junjunn + if (0 == dataOffset) + { +// by higepon +// bool readResult = drive_->read(lba, context->memory->Data, sectorSize) == 0; + bool readResult = drive_->read(lba, context->memory->Data, readSize) == 0; + if (!readResult) + { + return MONA_FAILURE; + } + } + else + { + uint8_t* temp = new uint8_t[sectorSize]; + if (temp == NULL) return MONA_FAILURE; + + bool readResult = drive_->read(lba, temp, sectorSize) == 0; + if (!readResult) + { + delete temp; + return MONA_FAILURE; + } + + memcpy(context->memory->Data, temp + dataOffset, readSize); + delete[] temp; + } + context->resultSize = readSize; + return MONA_SUCCESS; +#endif } int ISO9660FileSystem::seek(Vnode* file, uint32_t offset, uint32_t origin) Index: IDEDriver.cpp =================================================================== --- IDEDriver.cpp (リビジョン 3961) +++ IDEDriver.cpp (リビジョン 3962) @@ -17,6 +17,7 @@ using namespace MonAPI; //#define DEBUG_READ_TRACE +#define FAST_JUNJUNN 1 /*---------------------------------------------------------------------- IDEDRIVER @@ -357,7 +358,9 @@ outp8(controller, ATA_BLR, (uint8_t)(command->limit & 0xff)); outp8(controller, ATA_BHR, (uint8_t)(command->limit >> 8)); outp8(controller, ATA_CMR, 0xa0); +#ifndef FAST_JUNJUNN sleep(1); +#endif uint32_t i; for (i = 0; i < ATA_TIMEOUT; i++) @@ -455,7 +458,9 @@ } outp8(controllers, ATA_CMR, command->command); +#ifndef FAST_JUNJUNN sleep(1); +#endif /* wait busy clear */ if (!waitBusyClear(controller)) @@ -504,7 +509,9 @@ } outp8(controller, ATA_CMR, command->command); +#ifndef FAST_JUNJUNN sleep(1); +#endif /* read atlternate status once */ inp8(controller, ATA_ASR); @@ -708,11 +715,15 @@ { /* software reset */ outp8(controller, ATA_DCR, 0x06); +#ifndef FAST_JUNJUNN sleep(5); +#endif /* no interrupt */ outp8(controller, ATA_DCR, 0x02); +#ifndef FAST_JUNJUNN sleep(5); +#endif setDeviceTypeFirst(controller, MASTER); setDeviceTypeSecond(controller, MASTER); @@ -740,7 +751,7 @@ { /* select device */ outp8(controller, ATA_DHR, deviceValue(deviceNo)); - sleep(10); +// sleep(10); c = inp8(controller, ATA_STR); if (c == 0xff) break; @@ -800,7 +811,9 @@ { bool firstResult = commandIdentify(controller, deviceNo, buffer); int firstError = getLastError(); +#ifndef FAST_JUNJUNN sleep(5); +#endif bool secondResult = commandIdentify(controller, deviceNo, buffer); int secondError = getLastError(); @@ -863,7 +876,9 @@ if (whichController == controller && device->deviceNo == deviceNo) { outp8(controller, ATA_DHR, deviceValue(deviceNo)); +#ifndef FAST_JUNJUNN sleep(10); +#endif return true; } } @@ -872,9 +887,10 @@ /* select device */ outp8(controller, ATA_DHR, deviceValue(deviceNo)); +#ifndef FAST_JUNJUNN sleep(10); - if (!waitBusyAndDataRequestBothClear(controller)) return false; +#endif whichController = controller; whichController->selectedDevice = &controller->devices[deviceNo];