- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello, everyone. I am trying intel RTM now.
I am confusing that _xbegin() return 0 frequently. If _xbegin failed/ abort, it should return a abort status.https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/X86-transactional-memory-intrinsics.html
Here is my test code: There are 1000 accounts in a bank; A random account transfer 1$ to another random account each time.
for(int i=0; i<5000000; i++){
int src = rand()%bank->size;
int dst = rand()%bank->size;
//printf("src %d dst %d\n", src, dst);
while(src == dst){
dst = rand()%bank->size;
}
unsigned stat = _xbegin();
if(stat == _XBEGIN_STARTED){
bank->accounts[src].balance--;
bank->accounts[dst].balance++;
_xend();
tx[id]++;
}else{
_abort[id]++;
if (stat & _XABORT_CONFLICT){
conflict[id]++;
}
if (stat & _XABORT_CAPACITY){
capacity[id]++;
}
if (stat & _XABORT_DEBUG){
debug[id]++;
}
if (stat & _XABORT_RETRY == 0){
failed[id]++;
}
if (stat & _XABORT_NESTED){
printf("[ PANIC ] _XABORT_NESTED\n");
exit(-1);
}
if (stat & _XABORT_EXPLICIT){
printf("[ panic ] _XBEGIN_EXPLICIT\n");
exit(-1);
}
if (stat == 0){
// printf("[ panic] stat is zero\n");
// exit(-1);
}
}
}
I was wondering in which situation will the _xbegin() return 0?
- Tags:
- Parallel Computing
Link Copied
- « Previous
-
- 1
- 2
- Next »
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Mengxing, I ran several times before I posted. I use vs2015 instead of g++ to build the program. Could you show disassembly of the loops to confirm whether Jim's touch code is in effect or not?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>Could you show disassembly of the loops to confirm whether Jim's touch code is in effect or not?
Confirmation should be performed. In my opinion, the code optimization should NOT consider manipulation of volatile variables in "dead code" elimination. "volatile", as one of its definitions, declares that the memory location may be observed and/or modified by an external process not visible to the compiler.
If you find the Touch code optimized out, then as a work around you will have to write asm statements to perform the touch.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A simple trick is to print the variable 'Touch' as well, in case the compiler eliminates it...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jeremy,
If the Touch code were stripped, then the following may be better
if(zero == 999999999) printf("%d", Touch); // don't expect this to print
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry for response late.
I use gdb to disassemble the code, I am sure Touch is executed.
if (stat == 0){
0x0000000000400fc2 <+263>: cmpl $0x0,-0x4(%rbp)
0x0000000000400fc6 <+267>: jne 0x40105d <f1(Bank*, int)+418>
49 // ?? interrupt may have unmapped page holding [src] and/or [dst]
50 Touch = bank->accounts[src].balance + bank->accounts[dst].balance;
---Type <return> to continue, or q <return> to quit---
0x0000000000400fcc <+273>: mov -0x18(%rbp),%rax
0x0000000000400fd0 <+277>: mov (%rax),%rax
0x0000000000400fd3 <+280>: mov -0x8(%rbp),%edx
0x0000000000400fd6 <+283>: movslq %edx,%rdx
0x0000000000400fd9 <+286>: shl $0x6,%rdx
0x0000000000400fdd <+290>: add %rdx,%rax
0x0000000000400fe0 <+293>: mov (%rax),%rax
0x0000000000400fe3 <+296>: mov %eax,%edx
0x0000000000400fe5 <+298>: mov -0x18(%rbp),%rax
0x0000000000400fe9 <+302>: mov (%rax),%rax
0x0000000000400fec <+305>: mov -0xc(%rbp),%ecx
0x0000000000400fef <+308>: movslq %ecx,%rcx
0x0000000000400ff2 <+311>: shl $0x6,%rcx
0x0000000000400ff6 <+315>: add %rcx,%rax
0x0000000000400ff9 <+318>: mov (%rax),%rax
0x0000000000400ffc <+321>: add %edx,%eax
0x0000000000400ffe <+323>: mov %eax,0x2061fc(%rip) # 0x607200 <Touch>
51 zero[id]++;
0x0000000000401004 <+329>: mov 0x2061ed(%rip),%rax # 0x6071f8 <zero>
0x000000000040100b <+336>: mov -0x1c(%rbp),%edx
0x000000000040100e <+339>: movslq %edx,%rdx
0x0000000000401011 <+342>: shl $0x3,%rdx
0x0000000000401015 <+346>: add %rdx,%rax
0x0000000000401018 <+349>: mov (%rax),%rdx
0x000000000040101b <+352>: add $0x1,%rdx
0x000000000040101f <+356>: mov %rdx,(%rax)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I set "src=0" and "dst=1" instead of random number in my test (https://github.com/jrmwng/like2016/blob/test/jrmwng/why_xbegin_return_0/main.cpp).
From the disassembly, the 'Touch' assignment statement is followed by the 'zero' increment statement. It is different from the order in Jim's Touch codes (https://github.com/jrmwng/like2016/blob/test_jim/jrmwng/why_xbegin_return_0/main.cpp).
In addition, it'd be much clear if you dump addresses of relevant variables (e.g. addressof(src), addressof(dst), addressof(bank), addressof(bank->account), addressof(bank->account[src]), addressof(bank->account[dst]), addressof(zero), addressof(zero[id])) when the problem happens
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I also meet with the issues, I am confused about two problems:
1. _xbegin return 0 in one-thread situation;
2. conflicts happens when 2 threads access the independent locations. https://github.com/natsys/blog/blob/master/tsx.cc#L153-L158 this lines show that two threads access the independent data. and '_XABORT_CONFLICT' happens frequently.
BTW, are there some detail manual about RTM programming. I am a beginner, Thanks. :)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- « Previous
-
- 1
- 2
- Next »