|
Description
|
There is a benchmark called "compiler.compiler" in SPECjvm2007 (download from /net/javaperf/export/amurillo/SPECjvm2007/SPECjvm2007.kitv0.65.zip). I ran this benchmark on Solaris-sparc and run it inside Sun studio collect tool and found that addMetaName is on the top of the time consumed.
Looking into the current implementation and the disaseembly, I found that the following code is problematic in terms of the performance.
static int
addMetaName(jzfile *zip, const char *name, int length)
{
jint i;
if (zip->metanames == NULL) {
zip->metacount = 2;
zip->metanames = calloc(zip->metacount, sizeof(zip->metanames[0]));
if (zip->metanames == NULL) return -1;
}
for (i = 0; i < zip->metacount; i++) {
----> if (zip->metanames[i] == NULL) {
zip->metanames[i] = (char *) malloc(length+1);
if (zip->metanames[i] == NULL) return -1;
memcpy(zip->metanames[i], name, length);
zip->metanames[i][length] = '\0';
return 0;
}
}
The collect shows that loading "zip->metanames[i]" takes a great deal of time. This is most likely caused by L2 cache miss.
In fact, we don't need to look into each element of the array to find out which one to fill next. We could use a date member in jzfile to record the current meta slot. The following rewrite improved the score of the benchmark by 13 - 14% on Solaris sparc & x86.
static int
addMetaName(jzfile *zip, const char *name, int length)
{
jint i;
if (zip->metanames == NULL) {
zip->curMetaSlotCount = INITIAL_META_COUNT;
zip->metanames = calloc(zip->curMetaSlotCount, sizeof(zip->metanames[0]));
if (zip->metanames == NULL) return -1;
zip->curMetaSlot = 0;
}
i = zip->curMetaSlot;
if (i >= zip->curMetaSlotCount) {
/* No free entries in zip->metanames? */
if (growMetaNames(zip) != 0) return -1;
return addMetaName(zip, name, length);
}
zip->metanames[i] = (char *) malloc(length+1);
if (zip->metanames[i] == NULL) return -1;
memcpy(zip->metanames[i], name, length);
zip->metanames[i][length] = '\0';
zip->curMetaSlot++;
return 0;
}
Posted Date : 2007-08-01 07:08:25.0
|