Home » Developing U++ » U++ Developers corner » MT anomaly...
MT anomaly... [message #15324] |
Wed, 16 April 2008 12:29 |
|
mirek
Messages: 13975 Registered: November 2005
|
Ultimate Member |
|
|
I am now working on some advanced "MT topics" and have encountered this anomaly:
#include <Core/Core.h>
using namespace Upp;
#ifdef PLATFORM_POSIX
__thread int threadid;
#else
__declspec(thread) int threadid;
#endif
#define LLOG(x) LOG((threadid) << " " << x << ", count " << count)
RWMutex rwlock;
VectorMap<int, String> cache;
String Fn(int x)
{
return AsString(sin(sqrt((double)x)));
}
void CheckResult(int x, const String& r)
{
if(r != Fn(x)) {
DUMP(r);
DUMP(Fn(x));
Panic("Failure! " + AsString(threadid));
}
}
int writes, removes;
void WorkThread(int id)
{
threadid = id;
for(int i = 0; i < 200000000; i++) {
if(i % 10000 == 0)
INTERLOCKED
Cout() << id << ": " << i << ", writes: " << writes << ", removes: " << removes << "\n";
int x = rand() & 0x7fff;
rwlock.EnterRead();
int q = cache.Find(x);
if(q >= 0) {
String r = cache[q];
CheckResult(x, r);
for(int i = 0; i < 100; i++)
Fn(x);
rwlock.LeaveRead();
}
else {
rwlock.LeaveRead();
rwlock.EnterWrite();
q = cache.Find(x);
if(q >= 0)
CheckResult(x, cache[q]);
else {
writes++;
if(cache.GetCount() >= 0x7000) {
removes++;
cache.Remove(0, 100);
}
cache.Add(x, Fn(x));
}
rwlock.LeaveWrite();
}
}
}
CONSOLE_APP_MAIN
{
Thread t[20];
for(int i = 0; i < 9; i++)
t[i].Run(callback1(WorkThread, i + 1));
WorkThread(0);
for(int i = 0; i < 9; i++)
t[i].Wait();
}
This is basically a code to test RWMutex doing something reasonable - simulating cache.
This works as expected in Win32, fully utilizing both of my cores, but in Linux I am unable to get more than 60% CPU utilization. Obviously, some weird contention is involved, if only I would know why....
Any ideas?
Mirek
|
|
|
Re: MT anomaly... [message #15844 is a reply to message #15324] |
Sun, 11 May 2008 19:18 |
|
tvanriper
Messages: 85 Registered: September 2007 Location: Germantown, MD, USA
|
Member |
|
|
Maybe I'm totally off-base here, and I haven't looked at the code, but are you multi-threading at the kernel or user level?
If you're using the POSIX library calls, you're probably multi-threading through user level threading, which means you probably won't get at multiple cores. You're still multi-threading, but at the user level, you can't get at the other core; that requires a system call of some kind that most user level libraries know nothing about.
If you're using the system calls that Linux offers (kernel level threading), then I don't know why you're seeing this kind of performance; you should be seeing both cores used.
|
|
|
Re: MT anomaly... [message #15845 is a reply to message #15844] |
Sun, 11 May 2008 19:43 |
|
mirek
Messages: 13975 Registered: November 2005
|
Ultimate Member |
|
|
tvanriper wrote on Sun, 11 May 2008 13:18 | Maybe I'm totally off-base here, and I haven't looked at the code, but are you multi-threading at the kernel or user level?
If you're using the POSIX library calls, you're probably multi-threading through user level threading, which means you probably won't get at multiple cores. You're still multi-threading, but at the user level, you can't get at the other core; that requires a system call of some kind that most user level libraries know nothing about.
If you're using the system calls that Linux offers (kernel level threading), then I don't know why you're seeing this kind of performance; you should be seeing both cores used.
|
AFAIK, pthreads work through system threads.
In any case, 60% means I am actually USING another core...
Anyway, month later I think this is just example of contention problem...
Mirek
|
|
|
|
Goto Forum:
Current Time: Fri Mar 29 12:22:50 CET 2024
Total time taken to generate the page: 0.01598 seconds
|