Andres Freund <[email protected]> wrote:
> I think opannotate -a -s produces output with instructions/code
> intermingled.
Thanks. I'll check out perf later (thanks for the tips!), but for
now, here's the function which was at the top of my oprofile
results, annotated with those options. I'm afraid it's a bit
intimidating to me -- the last time I did much with X86 assembly
language was in the mid-80s, on an 80286. :-/ Hopefully, since
this is at the top of the oprofile results when running with
prepared statements, it will be of use to somebody.
The instructions which are shown as having that 1% still seem odd to
me, but as you say, they were probably actually waiting for some
previous operation to finish:
43329 0.3211 : 70b56a: test %rbp,%rbp
99903 0.7404 : 70b58a: mov %rax,0x18(%rsp)
If anyone wants any other detail from what I captured, let me know.
-Kevin
000000000070b520 <hash_search_with_hash_value>: /* hash_search_with_hash_value
total: 495463 3.6718 */
:hash_search_with_hash_value(HTAB *hashp,
: const
void *keyPtr,
: uint32
hashvalue,
:
HASHACTION action,
: bool
*foundPtr)
:{
5023 0.0372 : 70b520: push %r15
5967 0.0442 : 70b522: push %r14
1407 0.0104 : 70b524: mov %rdi,%r14
30 2.2e-04 : 70b527: push %r13
2495 0.0185 : 70b529: push %r12
2631 0.0195 : 70b52b: mov %edx,%r12d
18 1.3e-04 : 70b52e: push %rbp
1277 0.0095 : 70b52f: push %rbx
:static inline uint32
:calc_bucket(HASHHDR *hctl, uint32 hash_val)
:{
: uint32 bucket;
:
: bucket = hash_val & hctl->high_mask;
2122 0.0157 : 70b530: mov %edx,%ebx
:hash_search_with_hash_value(HTAB *hashp,
: const
void *keyPtr,
: uint32
hashvalue,
:
HASHACTION action,
: bool
*foundPtr)
:{
247 0.0018 : 70b532: sub $0x58,%rsp
236 0.0017 : 70b536: mov %rsi,0x10(%rsp)
3851 0.0285 : 70b53b: mov %ecx,0xc(%rsp)
2551 0.0189 : 70b53f: mov %r8,(%rsp)
: HASHHDR *hctl = hashp->hctl;
2225 0.0165 : 70b543: mov (%rdi),%r15
:static inline uint32
:calc_bucket(HASHHDR *hctl, uint32 hash_val)
:{
: uint32 bucket;
:
: bucket = hash_val & hctl->high_mask;
4544 0.0337 : 70b546: and 0x2c(%r15),%ebx
: if (bucket > hctl->max_bucket)
53409 0.3958 : 70b54a: cmp 0x28(%r15),%ebx
: 70b54e: jbe 70b554 <hash_search_with_hash_value+0x34>
: bucket = bucket & hctl->low_mask;
3324 0.0246 : 70b550: and 0x30(%r15),%ebx
: bucket = calc_bucket(hctl, hashvalue);
:
: segment_num = bucket >> hashp->sshift;
: segment_ndx = MOD(bucket, hashp->ssize);
:
: segp = hashp->dir[segment_num];
9702 0.0719 : 70b554: mov 0x58(%r14),%ecx
2428 0.0180 : 70b558: mov %ebx,%eax
489 0.0036 : 70b55a: mov 0x8(%r14),%rdx
: * Do the initial lookup
: */
: bucket = calc_bucket(hctl, hashvalue);
:
: segment_num = bucket >> hashp->sshift;
: segment_ndx = MOD(bucket, hashp->ssize);
391 0.0029 : 70b55e: mov 0x50(%r14),%r13
:
: segp = hashp->dir[segment_num];
2062 0.0153 : 70b562: shr %cl,%eax
309 0.0023 : 70b564: mov %eax,%eax
643 0.0048 : 70b566: mov (%rdx,%rax,8),%rbp
:
: if (segp == NULL)
43329 0.3211 : 70b56a: test %rbp,%rbp
1284 0.0095 : 70b56d: je 70b727
<hash_search_with_hash_value+0x207>
: hash_corrupted(hashp);
:
: prevBucketPtr = &segp[segment_ndx];
1878 0.0139 : 70b573: lea -0x1(%r13),%rax
: currBucket = *prevBucketPtr;
:
: /*
: * Follow collision chain looking for matching key
: */
: match = hashp->match; /* save one fetch in
inner loop */
35 2.6e-04 : 70b577: mov 0x18(%r14),%r13
: segp = hashp->dir[segment_num];
:
: if (segp == NULL)
: hash_corrupted(hashp);
:
: prevBucketPtr = &segp[segment_ndx];
41 3.0e-04 : 70b57b: and %ebx,%eax
434 0.0032 : 70b57d: lea 0x0(%rbp,%rax,8),%rbp
:
: /*
: * Follow collision chain looking for matching key
: */
: match = hashp->match; /* save one fetch in
inner loop */
: keysize = hashp->keysize; /* ditto */
2007 0.0149 : 70b582: mov 0x48(%r14),%rax
:
: if (segp == NULL)
: hash_corrupted(hashp);
:
: prevBucketPtr = &segp[segment_ndx];
: currBucket = *prevBucketPtr;
122 9.0e-04 : 70b586: mov 0x0(%rbp),%rbx
:
: /*
: * Follow collision chain looking for matching key
: */
: match = hashp->match; /* save one fetch in
inner loop */
: keysize = hashp->keysize; /* ditto */
99903 0.7404 : 70b58a: mov %rax,0x18(%rsp)
:
: while (currBucket != NULL)
1066 0.0079 : 70b58f: test %rbx,%rbx
: 70b592: jne 70b5ab <hash_search_with_hash_value+0x8b>
2273 0.0168 : 70b594: jmp 70b5d0 <hash_search_with_hash_value+0xb0>
: 70b596: nopw %cs:0x0(%rax,%rax,1)
: {
: if (currBucket->hashvalue == hashvalue &&
: match(ELEMENTKEY(currBucket), keyPtr,
keysize) == 0)
: break;
: prevBucketPtr = &(currBucket->link);
1362 0.0101 : 70b5a0: mov %rbx,%rbp
: currBucket = *prevBucketPtr;
655 0.0049 : 70b5a3: mov (%rbx),%rbx
: * Follow collision chain looking for matching key
: */
: match = hashp->match; /* save one fetch in
inner loop */
: keysize = hashp->keysize; /* ditto */
:
: while (currBucket != NULL)
608 0.0045 : 70b5a6: test %rbx,%rbx
: 70b5a9: je 70b5d0 <hash_search_with_hash_value+0xb0>
: {
: if (currBucket->hashvalue == hashvalue &&
3504 0.0260 : 70b5ab: cmp %r12d,0x8(%rbx)
98486 0.7299 : 70b5af: nop
1233 0.0091 : 70b5b0: jne 70b5a0 <hash_search_with_hash_value+0x80>
1750 0.0130 : 70b5b2: lea 0x10(%rbx),%rdi
310 0.0023 : 70b5b6: mov 0x18(%rsp),%rdx
871 0.0065 : 70b5bb: mov 0x10(%rsp),%rsi
131 9.7e-04 : 70b5c0: callq *%r13
2031 0.0151 : 70b5c3: test %eax,%eax
: 70b5c5: jne 70b5a0 <hash_search_with_hash_value+0x80>
822 0.0061 : 70b5c7: nopw 0x0(%rax,%rax,1)
: hash_collisions++;
: hctl->collisions++;
:#endif
: }
:
: if (foundPtr)
2268 0.0168 : 70b5d0: cmpq $0x0,(%rsp)
3831 0.0284 : 70b5d5: je 70b5e1 <hash_search_with_hash_value+0xc1>
: *foundPtr = (bool) (currBucket != NULL);
1411 0.0105 : 70b5d7: mov (%rsp),%rdx
951 0.0070 : 70b5db: test %rbx,%rbx
125 9.3e-04 : 70b5de: setne (%rdx)
:
: /*
: * OK, now what?
: */
: switch (action)
4249 0.0315 : 70b5e1: cmpl $0x1,0xc(%rsp)
928 0.0069 : 70b5e6: je 70b650
<hash_search_with_hash_value+0x130>
656 0.0049 : 70b5e8: jae 70b610 <hash_search_with_hash_value+0xf0>
: {
: case HASH_FIND:
: if (currBucket != NULL)
806 0.0060 : 70b5ea: test %rbx,%rbx
216 0.0016 : 70b5ed: je 70b78a
<hash_search_with_hash_value+0x26a>
: /* FALL THRU */
:
: case HASH_ENTER:
: /* Return existing element if found,
else create one */
: if (currBucket != NULL)
: return (void *)
ELEMENTKEY(currBucket);
2059 0.0153 : 70b5f3: lea 0x10(%rbx),%r13
: }
:
: elog(ERROR, "unrecognized hash action code: %d", (int)
action);
:
: return NULL; /* keep
compiler quiet */
:}
1418 0.0105 : 70b5f7: add $0x58,%rsp
445 0.0033 : 70b5fb: mov %r13,%rax
516 0.0038 : 70b5fe: pop %rbx
2323 0.0172 : 70b5ff: pop %rbp
1023 0.0076 : 70b600: pop %r12
1208 0.0090 : 70b602: pop %r13
1149 0.0085 : 70b604: pop %r14
1806 0.0134 : 70b606: pop %r15
1349 0.0100 : 70b608: retq
: 70b609: nopl 0x0(%rax)
: *foundPtr = (bool) (currBucket != NULL);
:
: /*
: * OK, now what?
: */
: switch (action)
1687 0.0125 : 70b610: cmpl $0x2,0xc(%rsp)
1815 0.0135 : 70b615: je 70b6d0
<hash_search_with_hash_value+0x1b0>
38 2.8e-04 : 70b61b: cmpl $0x3,0xc(%rsp)
34 2.5e-04 : 70b620: je 70b650
<hash_search_with_hash_value+0x130>
: }
:
: return (void *) ELEMENTKEY(currBucket);
: }
:
: elog(ERROR, "unrecognized hash action code: %d", (int)
action);
: 70b622: mov $0x86b6c0,%edx
: 70b627: mov $0x3c5,%esi
: 70b62c: mov $0x86b493,%edi
: 70b631: callq 7035f0 <elog_start>
: 70b636: mov 0xc(%rsp),%edx
: 70b63a: mov $0x86b5f0,%esi
: 70b63f: mov $0x14,%edi
: 70b644: xor %eax,%eax
: 70b646: xor %r13d,%r13d
: 70b649: callq 7033f0 <elog_finish>
: 70b64e: jmp 70b5f7 <hash_search_with_hash_value+0xd7>
: Assert(hashp->alloc != DynaHashAlloc);
: /* FALL THRU */
:
: case HASH_ENTER:
: /* Return existing element if found,
else create one */
: if (currBucket != NULL)
3030 0.0225 : 70b650: test %rbx,%rbx
: 70b653: jne 70b5f3 <hash_search_with_hash_value+0xd3>
: return (void *)
ELEMENTKEY(currBucket);
:
: /* disallow inserts if frozen */
: if (hashp->frozen)
2150 0.0159 : 70b655: cmpb $0x0,0x42(%r14)
1410 0.0104 : 70b65a: nopw 0x0(%rax,%rax,1)
11 8.2e-05 : 70b660: jne 70b998
<hash_search_with_hash_value+0x478>
: */
:static HASHBUCKET
:get_hash_entry(HTAB *hashp)
:{
: /* use volatile pointer to prevent code rearrangement */
: volatile HASHHDR *hctlv = hashp->hctl;
405 0.0030 : 70b666: mov (%r14),%rbx
251 0.0019 : 70b669: mov $0x1,%r13d
7 5.2e-05 : 70b66f: nop
2 1.5e-05 : 70b670: jmp 70b6a9
<hash_search_with_hash_value+0x189>
: 70b672: nopw 0x0(%rax,%rax,1)
: /* if partitioned, must lock to touch nentries
and freeList */
: if (IS_PARTITIONED(hctlv))
: SpinLockAcquire(&hctlv->mutex);
:
: /* try to get an entry from the freelist */
: newElement = hctlv->freeList;
824 0.0061 : 70b678: mov 0x10(%rbx),%rcx
: if (newElement != NULL)
5315 0.0394 : 70b67c: test %rcx,%rcx
: /* if partitioned, must lock to touch nentries
and freeList */
: if (IS_PARTITIONED(hctlv))
: SpinLockAcquire(&hctlv->mutex);
:
: /* try to get an entry from the freelist */
: newElement = hctlv->freeList;
242 0.0018 : 70b67f: mov %rcx,0x50(%rsp)
: if (newElement != NULL)
559 0.0041 : 70b684: jne 70b9c6
<hash_search_with_hash_value+0x4a6>
: break;
:
: /* no free elements. allocate another chunk of
buckets */
: if (IS_PARTITIONED(hctlv))
: 70b68a: mov 0x48(%rbx),%rax
: 70b68e: test %rax,%rax
: 70b691: je 70b696
<hash_search_with_hash_value+0x176>
: SpinLockRelease(&hctlv->mutex);
: 70b693: movb $0x0,(%rbx)
:
: if (!element_alloc(hashp, hctlv->nelem_alloc))
: 70b696: mov 0x6c(%rbx),%esi
: 70b699: mov %r14,%rdi
: 70b69c: callq 70b370 <element_alloc>
: 70b6a1: test %al,%al
: 70b6a3: je 70b7a9
<hash_search_with_hash_value+0x289>
: HASHBUCKET newElement;
:
: for (;;)
: {
: /* if partitioned, must lock to touch nentries
and freeList */
: if (IS_PARTITIONED(hctlv))
875 0.0065 : 70b6a9: mov 0x48(%rbx),%rax
2327 0.0172 : 70b6ad: test %rax,%rax
238 0.0018 : 70b6b0: je 70b678
<hash_search_with_hash_value+0x158>
137 0.0010 : 70b6b2: mov %r13d,%eax
88 6.5e-04 : 70b6b5: lock xchg %al,(%rbx)
: SpinLockAcquire(&hctlv->mutex);
6001 0.0445 : 70b6b8: test %al,%al
: 70b6ba: je 70b678
<hash_search_with_hash_value+0x158>
6 4.4e-05 : 70b6bc: mov $0x3d8,%edx
3 2.2e-05 : 70b6c1: mov $0x86b493,%esi
: 70b6c6: mov %rbx,%rdi
1 7.4e-06 : 70b6c9: callq 6342c0 <s_lock>
: 70b6ce: jmp 70b678
<hash_search_with_hash_value+0x158>
: if (currBucket != NULL)
: return (void *)
ELEMENTKEY(currBucket);
: return NULL;
:
: case HASH_REMOVE:
: if (currBucket != NULL)
4191 0.0311 : 70b6d0: test %rbx,%rbx
: 70b6d3: je 70b78a
<hash_search_with_hash_value+0x26a>
: {
: /* use volatile pointer to
prevent code rearrangement */
: volatile HASHHDR *hctlv = hctl;
:
: /* if partitioned, must lock to
touch nentries and freeList */
: if (IS_PARTITIONED(hctlv))
1161 0.0086 : 70b6d9: mov 0x48(%r15),%rax
1912 0.0142 : 70b6dd: test %rax,%rax
176 0.0013 : 70b6e0: je 70b6f3
<hash_search_with_hash_value+0x1d3>
22 1.6e-04 : 70b6e2: mov $0x1,%eax
27 2.0e-04 : 70b6e7: lock xchg %al,(%r15)
:
SpinLockAcquire(&hctlv->mutex);
6770 0.0502 : 70b6eb: test %al,%al
18 1.3e-04 : 70b6ed: jne 70b792
<hash_search_with_hash_value+0x272>
:
: Assert(hctlv->nentries > 0);
: hctlv->nentries--;
1385 0.0103 : 70b6f3: mov 0x8(%r15),%rax
5134 0.0380 : 70b6f7: sub $0x1,%rax
220 0.0016 : 70b6fb: mov %rax,0x8(%r15)
:
: /* remove record from hash
bucket's chain. */
: *prevBucketPtr =
currBucket->link;
490 0.0036 : 70b6ff: mov (%rbx),%rax
2146 0.0159 : 70b702: mov %rax,0x0(%rbp)
:
: /* add the record to the
freelist for this table. */
: currBucket->link =
hctlv->freeList;
749 0.0056 : 70b706: mov 0x10(%r15),%rax
118 8.7e-04 : 70b70a: mov %rax,(%rbx)
: hctlv->freeList = currBucket;
169 0.0013 : 70b70d: mov %rbx,0x10(%r15)
:
: if (IS_PARTITIONED(hctlv))
244 0.0018 : 70b711: mov 0x48(%r15),%rax
44 3.3e-04 : 70b715: test %rax,%rax
: 70b718: je 70b5f3 <hash_search_with_hash_value+0xd3>
:
SpinLockRelease(&hctlv->mutex);
22 1.6e-04 : 70b71e: movb $0x0,(%r15)
8 5.9e-05 : 70b722: jmpq 70b5f3 <hash_search_with_hash_value+0xd3>
:{
: /*
: * If the corruption is in a shared hashtable, we'd
better force a
: * systemwide restart. Otherwise, just shut down this
one backend.
: */
: if (hashp->isshared)
: 70b727: cmpb $0x0,0x40(%r14)
: 70b72c: je 70b75c
<hash_search_with_hash_value+0x23c>
: elog(PANIC, "hash table \"%s\" corrupted",
hashp->tabname);
: 70b72e: mov $0x86b6dc,%edx
: 70b733: mov $0x569,%esi
: 70b738: mov $0x86b493,%edi
: 70b73d: callq 7035f0 <elog_start>
: 70b742: mov 0x38(%r14),%rdx
: 70b746: mov $0x86b49e,%esi
: 70b74b: mov $0x16,%edi
: 70b750: xor %eax,%eax
: 70b752: callq 7033f0 <elog_finish>
: 70b757: jmpq 70b573 <hash_search_with_hash_value+0x53>
: else
: elog(FATAL, "hash table \"%s\" corrupted",
hashp->tabname);
: 70b75c: mov $0x86b6dc,%edx
: 70b761: mov $0x56b,%esi
: 70b766: mov $0x86b493,%edi
: 70b76b: callq 7035f0 <elog_start>
: 70b770: mov 0x38(%r14),%rdx
: 70b774: mov $0x86b49e,%esi
: 70b779: mov $0x15,%edi
: 70b77e: xor %eax,%eax
: 70b780: callq 7033f0 <elog_finish>
: 70b785: jmpq 70b573 <hash_search_with_hash_value+0x53>
: return (void *) ELEMENTKEY(currBucket);
: }
:
: elog(ERROR, "unrecognized hash action code: %d", (int)
action);
:
: return NULL; /* keep
compiler quiet */
433 0.0032 : 70b78a: xor %r13d,%r13d
103 7.6e-04 : 70b78d: jmpq 70b5f7 <hash_search_with_hash_value+0xd7>
: /* use volatile pointer to
prevent code rearrangement */
: volatile HASHHDR *hctlv = hctl;
:
: /* if partitioned, must lock to
touch nentries and freeList */
: if (IS_PARTITIONED(hctlv))
:
SpinLockAcquire(&hctlv->mutex);
10 7.4e-05 : 70b792: mov $0x36f,%edx
5 3.7e-05 : 70b797: mov $0x86b493,%esi
: 70b79c: mov %r15,%rdi
1 7.4e-06 : 70b79f: callq 6342c0 <s_lock>
1 7.4e-06 : 70b7a4: jmpq 70b6f3
<hash_search_with_hash_value+0x1d3>
:
: currBucket = get_hash_entry(hashp);
: if (currBucket == NULL)
: {
: /* out of memory */
: if (action == HASH_ENTER_NULL)
: 70b7a9: cmpl $0x3,0xc(%rsp)
: 70b7ae: je 70b78a
<hash_search_with_hash_value+0x26a>
: return NULL;
: /* report a generic message */
: if (hashp->isshared)
: 70b7b0: cmpb $0x0,0x40(%r14)
: 70b7b5: je 70bab1
<hash_search_with_hash_value+0x591>
: ereport(ERROR,
: 70b7bb: xor %r8d,%r8d
: 70b7be: mov $0x14,%edi
: 70b7c3: mov $0x86b6c0,%ecx
: 70b7c8: mov $0x3a0,%edx
: 70b7cd: mov $0x86b493,%esi
: 70b7d2: callq 702d60 <errstart>
: 70b7d7: test %al,%al
: 70b7d9: mov $0x848307,%edi
: 70b7de: jne 70bada
<hash_search_with_hash_value+0x5ba>
:
(errcode(ERRCODE_OUT_OF_MEMORY),
:
errmsg("out of shared memory")));
: else
: ereport(ERROR,
: 70b7e4: mov $0x10,%r13d
:
(errcode(ERRCODE_OUT_OF_MEMORY),
:
errmsg("out of memory")));
: }
:
: /* link into hashbucket chain */
: *prevBucketPtr = currBucket;
1997 0.0148 : 70b7ea: mov 0x50(%rsp),%rcx
: currBucket->link = NULL;
:
: /* copy key into record */
: currBucket->hashvalue = hashvalue;
: hashp->keycopy(ELEMENTKEY(currBucket),
keyPtr, keysize);
1108 0.0082 : 70b7ef: mov %r13,%rdi
:
(errcode(ERRCODE_OUT_OF_MEMORY),
:
errmsg("out of memory")));
: }
:
: /* link into hashbucket chain */
: *prevBucketPtr = currBucket;
11 8.2e-05 : 70b7f2: mov %rcx,0x0(%rbp)
: currBucket->link = NULL;
639 0.0047 : 70b7f6: movq $0x0,(%rcx)
:
: /* copy key into record */
: currBucket->hashvalue = hashvalue;
1539 0.0114 : 70b7fd: mov %r12d,0x8(%rcx)
: hashp->keycopy(ELEMENTKEY(currBucket),
keyPtr, keysize);
1262 0.0094 : 70b801: mov 0x18(%rsp),%rdx
191 0.0014 : 70b806: mov 0x10(%rsp),%rsi
157 0.0012 : 70b80b: callq *0x20(%r14)
: * Check if it is time to split a
bucket. Can't split if running
: * in partitioned mode, nor if table is
the subject of any active
: * hash_seq_search scans. Strange
order of these tests is to try
: * to check cheaper conditions first.
: */
: if (!IS_PARTITIONED(hctl) &&
483 0.0036 : 70b80f: cmpq $0x0,0x48(%r15)
343 0.0025 : 70b814: jne 70b5f7 <hash_search_with_hash_value+0xd7>
234 0.0017 : 70b81a: mov 0x28(%r15),%eax
127 9.4e-04 : 70b81e: mov 0x8(%r15),%rdx
257 0.0019 : 70b822: add $0x1,%eax
15 1.1e-04 : 70b825: mov %rax,%rcx
105 7.8e-04 : 70b828: mov %rdx,%rax
144 0.0011 : 70b82b: sar $0x3f,%rdx
165 0.0012 : 70b82f: idiv %rcx
12710 0.0942 : 70b832: cmp 0x50(%r15),%rax
: 70b836: jl 70b5f7 <hash_search_with_hash_value+0xd7>
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers