Why C++ fread is so different from Windows ReadFile

Greetings,
I write a piece of code to simulate system I/O perf. However the result is so different between fread (IOPS is 5000+) and Windows ReadFile (IOPS 200 ~ 300) for a 7200RPM HDD (it's 180 ~ 190 Random read IOPS by IOMeter). Could you give me a hint where's the problem?

Thanks.

Nai Yan.

Code - Windows ReadFile (with cache)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
DWORD WINAPI FileReadThreadEntry(LPVOID lpThreadParameter)
{
	//File access with cache enabled
	input * in = (input*) lpThreadParameter; 

	LPCTSTR path = (LPCTSTR) in->path;

	HANDLE fp = CreateFile(
		path,
		GENERIC_READ,
		FILE_SHARE_READ,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,//|FILE_FLAG_NO_BUFFERING,
		NULL);


	unsigned int sPos = in->starting;

	int * result = in->r;

	if(fp != NULL)
	{
		unsigned long pos;
		bool bRead;

		DWORD bNum;

		for (int i=0; i<length/(threadCount*interval);i++)
		{
			pos = i * interval;

			if ((SetFilePointer(fp,(sPos+pos),NULL,FILE_BEGIN)!=0))
			{
				if ((bRead = ReadFile(fp,&result[sPos/interval + i],512,&bNum,NULL))== true)
				{
					InterlockedIncrement(&completeIOs);
				}
				else
				{
					printf("file read err...\n");
					exit(-1);
				}
			}
		}			
		CloseHandle(fp);
		fp = NULL;
	}

	else
	{
		printf("File open err... \n");
		exit(-1);
	}
}


C++ fread code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
DWORD WINAPI FileReadThreadEntry(LPVOID lpThreadParameter)
{
	input * in = (input*) lpThreadParameter; 

	LPCTSTR path = (LPCTSTR) in->path;

	FILE * fp = fopen(path,"rb");

	int sPos = in->starting;

	int * result = in->r;

	if(fp != NULL)
	{
		fpos_t pos;
		for (int i=0; i<length/(threadCount*interval);i++)
		{
			pos = i * interval;
			fsetpos(fp,&pos);
			if (fread(&result[sPos/interval + i],512,1,fp) ==1)
			{
				InterlockedIncrement(&completeIOs);
			}
			else
			{
				printf("file read err...\n");
				exit(-1);
			}
		}

		fclose(fp);
		fp = NULL;
		}

	else
	{
		printf("File open err... \n");
		exit(-1);
	}
}
I am not sure what you mean by different but I guess you mean they have great difference in performance.

I am also not familiar with MS implementations so can be great help but why did you expect to perform the same? They probably use different approaches and this results to different performances.

If you are satisfied with the faster implementation stick with it. If you think there is some feature you cannot lose in the slower one pick this. It's that simple
C file streams opened with std::fopen() perform buffered reads and writes.

Win32 CreateFile() also uses buffering based on the hint provided by the programmer; you may be able to improve performance noticeably by specifying FILE_FLAG_SEQUENTIAL_SCAN.
Topic archived. No new replies allowed.