On Thu, Aug 22, 2013 at 5:04 PM, Sascha Wildner <[email protected]> wrote:
> On Mon, 19 Aug 2013 09:55:12 +0200, Dongsheng Song
> <[email protected]> wrote:
>
>> Hi,
>>
>> When I running DragonFlyBSD under VMware ESXi 5.1, with the following
>> setting:
>>
>> CPUs: 8
>> Memory: 4096 MB
>> SCSI controller: LSI Logic Paraller
>> SCSI disk size: 64G
>>
>> I found this VM is very very slowly, then I check the dmesg output,
>> I'm very surprised:
>>
>> da0: 3.300MB/s transfers
>
>
> As a datapoint: I tried this morning in latest VMware Player (Windows 8
> host). While I am seeing the same weird transfer rate in dmesg (da0:
> 3.300MB/s transfers), the disk's speed looked OK to me, using the dd test
> you did (speeds were around 80MB/s).
>
> Sascha
VMware desktop disk IO have much different than ESXi. I had write a
simple program,
use O_DIRECT|O_SYNC, then these test results is stable:
16.2 ~ 18.4 MB/s Linux
1.4 ~ 1.8 MB/s FreeBSD 9.1
0.2 ~ 0.4 MB/s DFLY master
So merge mpt (LSI Logic) driver from FreeBSD is valuable, but
unfortunately, I no suck skill.
Dongsheng
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <time.h>
#include <unistd.h>
static int block_align = 4096;
static int block_size = 1024 * 1024;
static int max_file_size = 1024 * 1024 * 1024;
static int stat_interval = 5;
static int should_stop = 0;
static uintptr_t *write_counter;
static char *tmp_file_name = "/tmp/tmp-01G.img";
static void write_loop();
static void stat_loop();
void *aligned_alloc(size_t alignment, size_t size);
static void
signal_handler(int signum)
{
should_stop = 1;
}
int main()
{
pid_t pid;
write_counter = mmap(NULL, sizeof(uintptr_t), PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
if (write_counter == MAP_FAILED) {
fprintf(stderr, "mmap failed: %d\n", errno);
exit(1);
}
pid = fork();
if (pid == 0) {
write_loop();
exit(0);
} else if (pid < 0) {
fprintf(stderr, "fork failed: %d\n", errno);
exit(1);
}
if (signal(SIGCHLD, signal_handler) == SIG_ERR
|| signal(SIGINT, signal_handler) == SIG_ERR
|| signal(SIGTERM, signal_handler) == SIG_ERR
) {
fprintf(stderr, "signal failed: %d\n", errno);
exit(1);
}
stat_loop();
kill(pid, SIGTERM);
return 0;
}
static void stat_loop()
{
uintptr_t b1, b2;
struct timespec t1, t2, ts1, ts2;
while(!should_stop && *write_counter == 0) {
ts1.tv_sec = 0;
ts1.tv_nsec = 100000;
nanosleep(&ts1, &ts2);
}
if(should_stop)
return;
b1 = *write_counter;
clock_gettime(CLOCK_MONOTONIC, &t1);
while(1) {
ts1.tv_sec = stat_interval;
ts1.tv_nsec = 0;
nanosleep(&ts1, &ts2);
if(should_stop)
return;
b2 = *write_counter;
clock_gettime(CLOCK_MONOTONIC, &t2);
fprintf(stdout, "%.3lf MB/s\n", (b2 - b1) / 1048576.0 / ((t2.tv_sec - t1.tv_sec) + (t2.tv_nsec - t1.tv_nsec) / 1000000000.0));
b1 = b2;
t1.tv_sec = t2.tv_sec;
t1.tv_nsec = t2.tv_nsec;
}
}
static void write_loop()
{
int rc, fd, offset = 0;;
char *buffer;
fd = open(tmp_file_name, O_CREAT|O_TRUNC|O_WRONLY|O_DIRECT|O_SYNC, 0x0666);
if (fd == -1) {
fprintf(stderr, "open failed: %d\n", errno);
exit(1);
}
rc = posix_memalign((void **) &buffer, block_align, block_size);
if (buffer == NULL) {
fprintf(stderr, "posix_memalign failed: %d\n", rc);
exit(1);
}
while(1) {
ssize_t rc = write(fd, buffer, block_size);
if (rc == -1) {
fprintf(stderr, "write failed: %d\n", errno);
exit(1);
}
*write_counter += rc;
offset += rc;
if (offset >= max_file_size) {
if(0 != lseek(fd, 0, SEEK_SET)) {
fprintf(stderr, "lseek failed: %d\n", errno);
exit(1);
}
offset = 0;
}
}
}