G
golden
Hello,
I am going to ask a question regarding
write and lseek. I will provide code at the end of this, but first
some background.
I am trying to identify the cause of some latency in writing to disk.
My user claims that performance is much slower on SAN than on local
disk. The developer provided me a C++ program that performed a write
test that confirmed his suspicions. I modified the code to better
fit
my needs which it does now.
What I found during the test is that fsync is an expensive operation
and will block waiting for a confirmation from the disk device. What
I am trying to understand is the lseek function.
From what I read, it simply moves the pointer in the file descriptor
as directed. When I use this lseek function, writes are faster.
My question is why? When I use the write command, does the pointer
get reset and on each write, it will search for EOF?
This is running Linux sytem.
Thanks in advance:
#include <sys/types.h>
#include <sys/time.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv)
{
struct timeval start, end;
double usecs;
long val;
int ch, fd, idx, ops, numThreads;
char *fname= "";
int filesize = 40000000;
int bytes = 0;
bool dosync = true, doSeek=false;
bytes = 0;
ops = 0;
char *buf = new char[bytes];
fname = argv[1];
while (( ch = getopt(argc,argv, "b:f:sl")) != EOF)
switch (ch) {
case 'b' :
bytes = atoi(optarg);
break;
case 'o' :
ops = atoi(optarg);
break;
case 'f' :
fname = (optarg);
break;
case 's' :
dosync = false;
break;
case 'l' :
doSeek = true;
break;
}
argc -= optind;
argv += optind;
gettimeofday(&start,NULL);
memset(buf,0,bytes);
if ( dosync ) {
printf("Processing %d bytes with %d Operations of fsync :
\t", bytes,ops);
} else {
printf("Processing %d bytes with %d Operations of fsync :
\t", bytes,1);
}
// unlink(fname);
if ((fd = open(fname, O_RDWR | O_CREAT, 0666)) == -1)
{
int errNum = errno;
printf("ERROR: failed to open %s: n",fname);
return(0);
}
for ( int idx(0) ; idx < ops ; idx++)
{
if (write(fd, buf, bytes) != bytes)
{
printf("write: \n");
exit (1);
}
if ( dosync ) {
if (fsync(fd) != 0)
{
printf("fsync: \n");
exit (1);
}
}
if ( doSeek )
{
if (lseek(fd, (off_t)0, SEEK_SET) == -1)
{
printf("lseek: %s\n",
strerror(errno));
exit (1);
}
}
}
// One last sync
if (fsync(fd) != 0)
{
printf("fsync: \n");
exit (1);
}
gettimeofday(&end,NULL);
int totalSec = 0;
long totalUSec = 0;
if (start.tv_usec > end.tv_usec) {
end.tv_usec += 1000000;
end.tv_sec--;
}
totalSec = end.tv_sec - start.tv_sec;
totalUSec = end.tv_usec - start.tv_usec;
int t = totalSec + (totalUSec / 1000000);
printf("%ld Hours ",t / ( 60 * 60));
t %= (60*60);
printf("%ld Minutes ",t / 60);
t %= 60;
printf("%ld.%ld Seconds ",t ,totalUSec);
printf("%ld.%ld Seconds\n ",totalSec ,totalUSec);
}
I am going to ask a question regarding
write and lseek. I will provide code at the end of this, but first
some background.
I am trying to identify the cause of some latency in writing to disk.
My user claims that performance is much slower on SAN than on local
disk. The developer provided me a C++ program that performed a write
test that confirmed his suspicions. I modified the code to better
fit
my needs which it does now.
What I found during the test is that fsync is an expensive operation
and will block waiting for a confirmation from the disk device. What
I am trying to understand is the lseek function.
From what I read, it simply moves the pointer in the file descriptor
as directed. When I use this lseek function, writes are faster.
My question is why? When I use the write command, does the pointer
get reset and on each write, it will search for EOF?
This is running Linux sytem.
Thanks in advance:
#include <sys/types.h>
#include <sys/time.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv)
{
struct timeval start, end;
double usecs;
long val;
int ch, fd, idx, ops, numThreads;
char *fname= "";
int filesize = 40000000;
int bytes = 0;
bool dosync = true, doSeek=false;
bytes = 0;
ops = 0;
char *buf = new char[bytes];
fname = argv[1];
while (( ch = getopt(argc,argv, "b:f:sl")) != EOF)
switch (ch) {
case 'b' :
bytes = atoi(optarg);
break;
case 'o' :
ops = atoi(optarg);
break;
case 'f' :
fname = (optarg);
break;
case 's' :
dosync = false;
break;
case 'l' :
doSeek = true;
break;
}
argc -= optind;
argv += optind;
gettimeofday(&start,NULL);
memset(buf,0,bytes);
if ( dosync ) {
printf("Processing %d bytes with %d Operations of fsync :
\t", bytes,ops);
} else {
printf("Processing %d bytes with %d Operations of fsync :
\t", bytes,1);
}
// unlink(fname);
if ((fd = open(fname, O_RDWR | O_CREAT, 0666)) == -1)
{
int errNum = errno;
printf("ERROR: failed to open %s: n",fname);
return(0);
}
for ( int idx(0) ; idx < ops ; idx++)
{
if (write(fd, buf, bytes) != bytes)
{
printf("write: \n");
exit (1);
}
if ( dosync ) {
if (fsync(fd) != 0)
{
printf("fsync: \n");
exit (1);
}
}
if ( doSeek )
{
if (lseek(fd, (off_t)0, SEEK_SET) == -1)
{
printf("lseek: %s\n",
strerror(errno));
exit (1);
}
}
}
// One last sync
if (fsync(fd) != 0)
{
printf("fsync: \n");
exit (1);
}
gettimeofday(&end,NULL);
int totalSec = 0;
long totalUSec = 0;
if (start.tv_usec > end.tv_usec) {
end.tv_usec += 1000000;
end.tv_sec--;
}
totalSec = end.tv_sec - start.tv_sec;
totalUSec = end.tv_usec - start.tv_usec;
int t = totalSec + (totalUSec / 1000000);
printf("%ld Hours ",t / ( 60 * 60));
t %= (60*60);
printf("%ld Minutes ",t / 60);
t %= 60;
printf("%ld.%ld Seconds ",t ,totalUSec);
printf("%ld.%ld Seconds\n ",totalSec ,totalUSec);
}