From: Theodore Tso <tytso@mit.edu>
To: Kazuya Mio <k-mio@sx.jp.nec.com>
Cc: linux-ext4@vger.kernel.org
Subject: Re: [PATCH] e2fsck: Improve consistency check of uninit block group and some cleanup
Date: Fri, 3 Jul 2009 11:17:24 -0400 [thread overview]
Message-ID: <20090703151724.GE15038@mit.edu> (raw)
In-Reply-To: <4A4C450C.6060808@sx.jp.nec.com>
Hi Kazuya-san,
Many thanks for sending this patch. Couple of comments about it.
1) Please send clean-up patches separately. The "remove unnecessary
continue statement" I could easily separate out, but it wasn't
immediately obvious what "fix loop counter properly" was all about.
2) Requiring the allocation of a zero buffer to be passed into
ext2fs_test_bits() is *really* ugly. I'll note that the only reason
why it's faster to use memcmp() is because the C compiler has
optimized it so that it can use custom assembly that can compare the
memory block 32 bits at a time, after accounting for alignment
restrictions. In fact, comparing one block of memory against another
block of known-zero memory should trash our D-cache, and in theory it
should be faster to simply check the block of memory for non-zero
bytes.
In addition, in the future (see the 64-bit e2fsprogs patches in the
'pu' branch), bitmaps will be hidden behind an abstraction, so testing
against a known block isn't going to be easy or convenient; but having
an ext2fs_test_zero_range() does make a lot of sense. (For example,
if we use a AVL tree with extent encodings for a compact in-memory
bitmap representation to save memory usage for very large filesystems,
implementing ext2fs_test_zero_range() might be trivially easy)
So what I would suggest doing is to use the mem_is_zero() function
defined in the attached test program. This way at least we don't have
to pass in a huge chunk of zero-ed memory. If we really cared we
could write optimized x86 and x86-64 assembly that further optimized
mem_is_zero(), but this is probably good enough for now. I did some
testing, and it looks like that 256 bytes seems to minimize the loop
overhead, and gives us a win in terms of minimizing the D-cache used
for zero-buffer --- and 256 bytes is small enough that we can afford
to simply use a statically allocated zero buffer, so we don't have to
pass it into the library function.
Do you think you could make these changes and resend the patch?
Thanks,
- Ted
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <string.h>
struct resource_track {
struct timeval time_start;
struct timeval user_start;
struct timeval system_start;
};
void init_resource_track(struct resource_track *track)
{
struct rusage r;
gettimeofday(&track->time_start, 0);
getrusage(RUSAGE_SELF, &r);
track->user_start = r.ru_utime;
track->system_start = r.ru_stime;
}
#ifdef __GNUC__
#define _INLINE_ __inline__
#else
#define _INLINE_
#endif
static _INLINE_ float timeval_subtract(struct timeval *tv1,
struct timeval *tv2)
{
return ((tv1->tv_sec - tv2->tv_sec) +
((float) (tv1->tv_usec - tv2->tv_usec)) / 1000000);
}
void print_resource_track(const char *desc, struct resource_track *track)
{
struct rusage r;
struct timeval time_end;
gettimeofday(&time_end, 0);
if (desc)
printf("%s: ", desc);
getrusage(RUSAGE_SELF, &r);
printf("time: %5.2f/%5.2f/%5.2f\n",
timeval_subtract(&time_end, &track->time_start),
timeval_subtract(&r.ru_utime, &track->user_start),
timeval_subtract(&r.ru_stime, &track->system_start));
}
int mem_is_zero(const char *mem, size_t len)
{
static const char zero_buf[256];
while (len >= sizeof(zero_buf)) {
if (memcmp(mem, zero_buf, sizeof(zero_buf)))
return 0;
len -= sizeof(zero_buf);
mem += sizeof(zero_buf);
}
/* Deal with leftover bytes. */
if (len)
return !memcmp(mem, zero_buf, len);
return 1;
}
int mem_is_zero2(char *p, unsigned len)
{
while (len--)
if (*p++)
return 0;
return 1;
}
#define LEN 4096
char a[LEN], b[LEN];
main(int argc, char **argv)
{
struct resource_track r;
int i, j;
memset(a, 0, LEN);
memset(b, 0, LEN);
init_resource_track(&r);
for (i=0; i < 102400; i++)
if (memcmp(a, b, LEN))
printf("a is non-zero\n");
print_resource_track("memcmp", &r);
init_resource_track(&r);
for (i=0; i < 102400; i++)
if (!mem_is_zero(a, LEN))
printf("a is non-zero\n");
print_resource_track("mem_is_zero", &r);
init_resource_track(&r);
for (i=0; i < 102400; i++)
if (!mem_is_zero2(a, LEN))
printf("a is non-zero\n");
print_resource_track("mem_is_zero2", &r);
}
next prev parent reply other threads:[~2009-07-03 15:17 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-02 5:26 [PATCH] e2fsck: Improve consistency check of uninit block group and some cleanup Kazuya Mio
2009-07-03 15:17 ` Theodore Tso [this message]
2009-07-06 8:12 ` Kazuya Mio
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090703151724.GE15038@mit.edu \
--to=tytso@mit.edu \
--cc=k-mio@sx.jp.nec.com \
--cc=linux-ext4@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).