Homebrew [Developer Question] What is the expected read/write speed for the internal SD card (on Ninjhax)?

d0k3

3DS Homebrew Legend
OP
Member
Joined
Dec 3, 2004
Messages
2,786
Trophies
1
XP
3,896
Country
Germany
A question to the developers here:

What is the expected read/write speed for the internal 3DS SD card? I'm testing with a small program (3DSX, running via Ninjhax, on N3DS) I wrote myself and have CTRUlib and CTRcommon installed, if that matters. And, it is much too slow.


I've read somewhere that O3DS read / write speeds are equivalent to a class 4 SD. That would mean a write speed of 4Mbit / sec, which would be somewhat slow, but still acceptable. However, reading should be quite fast, because otherwise reading installed CIAs of sizes 1GB and above would take ages.


And, related question, what (C/C++ standard) functions would you suggest to use to copy a file from SD to SD?
 

d0k3

3DS Homebrew Legend
OP
Member
Joined
Dec 3, 2004
Messages
2,786
Trophies
1
XP
3,896
Country
Germany
Oh well, I asked an actual developer question on GBATemp... I'll try to answer it myself, maybe someone can help.

I've seen that CTRUlib comes with it's own function for reading / writing files. They seem to be more low level than fopen / fread / fwrite in C, but they also seem difficult to use. Especially because there are no examples for that and there is virtually no documentation for CTRUlib.

So is it recommended to use these instead of the typical C/C++ functions? Can anyone provide an example?
 

hippy dave

BBMB
Member
Joined
Apr 30, 2012
Messages
9,858
Trophies
2
XP
28,904
Country
United Kingdom
I was looking at the blargsnes source (specifically ui_rommenu.c mostly) for example code to read directories using ctrulib's functions. I've plonked those instructions into the code I'm porting and they work fine mixed with the existing fopen/fread etc.
 

elhobbs

Well-Known Member
Member
Joined
Jul 28, 2008
Messages
1,044
Trophies
1
XP
3,030
Country
United States
Oh well, I asked an actual developer question on GBATemp... I'll try to answer it myself, maybe someone can help.

I've seen that CTRUlib comes with it's own function for reading / writing files. They seem to be more low level than fopen / fread / fwrite in C, but they also seem difficult to use. Especially because there are no examples for that and there is virtually no documentation for CTRUlib.

So is it recommended to use these instead of the typical C/C++ functions? Can anyone provide an example?
Ctrulib supports standard C fopen etc. look at the source on github there are examples. Better yet download the source and build and install it. The repository is updated quite frequently with fixes and additional functionality. The installer version does not get updated as frequently.
 

d0k3

3DS Homebrew Legend
OP
Member
Joined
Dec 3, 2004
Messages
2,786
Trophies
1
XP
3,896
Country
Germany
I was looking at the blargsnes source (specifically ui_rommenu.c mostly) for example code to read directories using ctrulib's functions. I've plonked those instructions into the code I'm porting and they work fine mixed with the existing fopen/fread etc.
Yeah, but the problem is... copying a file via fopen / fread / fwrite seems to be awfully slow (an estimate 100kB / sec). Something seems wrong there.

You may also take a look at my copy function:
Code:
bool fsPathCopy(const std::string path, const std::string dest, std::function<bool(u64 pos, u64 totalSize)> onProgress) {
   if(fsIsDirectory(path)) {
        if(mkdir(dest.c_str(), 0777) != 0) return false;
        std::vector<FileInfo> contents = fsGetDirectoryContents(path);
        for (std::vector<FileInfo>::iterator it = contents.begin(); it != contents.end(); it++)
            if (!fsPathCopy((*it).path, dest + "/" + (*it).name)) return false;
        return true;
    } else {
        bool ret = false;
        u8 buffer[BUFSIZ];
        u64 total = fsGetFileSize(path);
        u64 pos = 0;
        u64 size;
        FILE* fp = fopen(path.c_str(), "rb");
        FILE* fd = fopen(dest.c_str(), "wb");
        if ((fp != NULL) && (fd != NULL)) {
            while ((size = fread(buffer, 1, BUFSIZ, fp)) > 0) {
                pos += fwrite(buffer, 1, size, fd);
                if((onProgress != NULL) && !onProgress(pos, total)) break;
            }
            ret = (pos == total);
        }
        if(fp != NULL) fclose(fp);
        if(fd != NULL) fclose(fd);
        return ret;
    }
}
This also uses functions from SteveIce10's CTRcommon library, just so you know.

Ctrulib supports standard C fopen etc. look at the source on github there are examples. Better yet download the source and build and install it. The repository is updated quite frequently with fixes and additional functionality. The installer version does not get updated as frequently.
Yup, I already got the latest version from Github. Compiled and installed from there.
 

elhobbs

Well-Known Member
Member
Joined
Jul 28, 2008
Messages
1,044
Trophies
1
XP
3,030
Country
United States
What does onProgress do? If it is updating the display you may be inadvertently adding a wait for vblank each time through the loop. That will definitely slow things down depending on your buffer size.
 

d0k3

3DS Homebrew Legend
OP
Member
Joined
Dec 3, 2004
Messages
2,786
Trophies
1
XP
3,896
Country
Germany
What does onProgress do? If it is updating the display you may be inadvertently adding a wait for vblank each time through the loop. That will definitely slow things down depending on your buffer size.

Nope, it's not because of onProgress. OnProgress only updates maximally 101 times per operation (0%...100%), plus I already tried leaving that out completely. I did get a significant speed increase by adjusting the buffer size now, though. Still a bit unhappy. I guess writing to / from SD is just a bit slow on 3DS anyways.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    K3Nv2 @ K3Nv2: https://youtu.be/MddR6PTmGKg?si=mU2EO5hoE7XXSbSr