|
Hi,
I'm working on a calculation module which handles a lot of small calculations. A sqeuencial approach is not feasible due to the amount of calculations (the biggest batch is approximately 15 million calculations) and my initial run projected 83 days in the worst case scenario. This is too long.
Since the threadpool is described as a good solution for many short calculations, I decided to give it a try. My implementation works on a small scale (15k calculations) and performs acceptable given 40 threads (dual-core, so max ideal number is max 50 according to the msdn documentation, but then the system threads are starving and timers run out of sync and GC freezes).
My only problem is, when I feed my small jobs to the queue, it fills the first batch of empty threads and then continues queuing, but *not* executing the jobs which are queued for processing. At a certain point, on the small scale, it has completed queuing, and *then* it starts processing the requests very fast. This is not sustainable, since when filling the queue, the system slowly grinds to a halt queuing slower per job.
To get an idea of a run: one calculation costs 25-500ms to complete, around 15 calculations per context, and about 1 million contexts to be processed per run.
Anyone can help me find an answer why the threadpool continues to queue but not process the queued jobs until the queuing is complete? Thanks in advance.
The consumer isn't a moron; she is your wife.
|
|
|
|
|
Helfdane wrote: Anyone can help me find an answer why the threadpool continues to queue but not process the queued jobs until the queuing is complete? Thanks in advance.
Even if they can, you are chasing the wrong problem. With only two cores you are not gaining anything by trying to pool a million operations. There is a logical maximum benefit of running twice as fast by using both cores equally. However you cannot attain the maximum because there is overhead of managing the pool and context switching between threads and other resources being used by the system.
You might be better off just creating two threads and splitting your operations in half running half in each thread.
Since you did not mention it, I should ask if you know about distributed computing? This would be the most common solution using PC's to reduce a 83 day workload.
led mike
|
|
|
|
|
Thank you and Dave for your replies.
Distributed computing is not an option, since it's an application that is installed at the customer and has to run standalone (it's a critical application where most clients prefer to hook it off the network).
About the threads, I was only following the MSDN documentation where they mention that 25 threads per core is the max ideal number where the overhead would still be smaller than the improvement per thread.
I forgot to mention, each calculation *might* need some additional information from the DB, hence the threading.
My problem is not the load or the number of threads, they are parameters on an existing infrastructure. My question is, why the threads are not working (are they on hold/in wait?) while queuing the jobs (is this infrastructure the right one?). Since you and Dave Kreskowiak propose less threads which I can agree on, the queuing will still be there, thus my problem still exists as the queuing still takes time while the threads do nothing (cpu load during queuing is not above 40%, so the other 60% should be used to do the first calculations but it doesn't use the 60% unless queuing is completed).
The consumer isn't a moron; she is your wife.
|
|
|
|
|
Helfdane wrote: the MSDN documentation where they mention that 25 threads per core is the max ideal number where the overhead would still be smaller than the improvement per thread.
Yes but for what use model? Threading is mostly related to multi-user processing. You want to maximize threads in that use model to share the compute cycles across users so that they don't wait one at a time for a reply. This is not your use model.
Helfdane wrote: why the threads are not working (are they on hold/in wait?)
Debugging threaded code is difficult when you are there, we are not. We are mostly guessing at this based on the information you have provided. One thing we do not know is how many jobs you queued. You threw out some numbers like 15 million. That's a large number for a PC. Given your use model I would research using two threads and a design that allows each thread to process half the calculations.
Resources are another issue when you start talking numbers like 15 million. I would wonder how much resources each calculation requires, I mean if there is some source data used for each calculation and you load all 15 million calculation resources at once you probably start having a lot of paging which slows everything down, as opposed to getting the resources only when needed.
I don't know what your experience and background is but writing efficient code requires a lot of in depth knowledge and experience. You have to understand hardware as well as software. Most of that is beyond my expertise, but I do understand you can't just read a threading article to get up to speed.
led mike
|
|
|
|
|
You have valid points, thanks for your input.
We are talking a multi-user environment, that is, multiple users can do a request for a number of calculations (there is one dispatcher which processes the requests by transforming it into the format used by the calculation engine. This dispatcher will probably have a WCF component for the thin clients to talk to, this is not final yet. In addition, the dispatcher will have the possibility of throttling the requests if the queue becomes too big, but that is something I haven't worked out yet; it's still on the drawing board). The dispatcher is designed to also monitor the system resources, as on which it will base his throttling and batching strategy. This should lessen the preassure on the hardware as well.
The test-case I had was 15k calculations (1000 base calculations with 15 subcalculations each in testing data). This means that when the calculation starts, 15k calculations are in the queue. The thing which hints me that nothing is happening is, that when queuing the first action of a calculation, the calculation routine is sending a notification to the console that it is starting, but the starting message never gets there unless queuing is done and so is the load.
I am not sure if my current infrastructure will be sufficient, hence my research and these forum postings, as I am not sure if I want to use a component (the threadpool in this case) where I cannot predict exactly what will happen. I think I do need threading since missing parts required for a calculation need to be fetched from the DB and/or are dependant on other calculations.
My background is saas with an average load of 500+ simultanious connections for clients who operate globally. My background is not primarily with .net.
The consumer isn't a moron; she is your wife.
|
|
|
|
|
Helfdane wrote: performs acceptable given 40 threads
40 threads on a dual core? It can perform better if you use few threads. Under that load, you're spending an awful lot of time doing context switching going from thread to thread to thread.
|
|
|
|
|
Didn't I say that?
led mike
|
|
|
|
|
Sometimes is multiple people tell him the same thing, it might sink in that it's not a good idea.
|
|
|
|
|
Dave Kreskowiak wrote: it might sink in
LMAO, I hear you. I did have that sinking feeling while typing my reply to the OP.
led mike
|
|
|
|
|
In a (VB).NET application I have changed the roaming property of an user setting from false to true.
If I run the application the setting is now written (through my.settings.save) to the roaming user.config, but if I restart the application the setting is still being read from the local user.config !
Only if I delete the entry (manually) from the local user.config, then the setting is being read from the roaming user.config.
Somewhere in MSDN I read that if there were duplicate settings in local and roaming, the roaming one should override the local; in my case this seems only true for the writing of the setting.
Is this "bug" Microsoft's or mine ?
|
|
|
|
|
Hi I am trying to build a bluetooth application. I am trying to connect my laptop to my phone. This is the code i am using. I dont know why i keep getting this winsock error 10014. I looked into MSDN which says
"Bad address.
The system detected an invalid pointer address in attempting to use a pointer argument of a call. This error occurs if an application passes an invalid pointer value, or if the length of the buffer is too small. For instance, if the length of an argument, which is a sockaddr structure, is smaller than the sizeof(sockaddr)."
I am not sure how to check the buffer and how can i find out whats wrong. Please help me i am stuck!!!
///// My code/////////////////////
#include "stdafx.h"
#include <initguid.h>
#include <winsock2.h>
#include <ws2bth.h>
#include <stdio.h>
DEFINE_GUID(OBEXFileTransfer, 0x00001106, 0x0000, 0x1000, 0x80,0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb);
int SDPGetPort( const char *addr, LPGUID guid )
{
int port = 0;
HANDLE h;
WSAQUERYSET *qs;
DWORD flags = 0;
DWORD qs_len;
bool done;
qs_len = sizeof(WSAQUERYSET);
qs = (WSAQUERYSET*) malloc( qs_len );
ZeroMemory( qs, qs_len );
qs->dwSize = sizeof(WSAQUERYSET);
qs->lpServiceClassId = guid;
qs->dwNameSpace = NS_BTH;
qs->dwNumberOfCsAddrs = 0;
qs->lpszContext = (LPSTR) addr;
flags = LUP_FLUSHCACHE | LUP_RETURN_ADDR;
wprintf (L"GUID ,%d %d",&qs_len,sizeof(WSAQUERYSET) );
if( SOCKET_ERROR == WSALookupServiceBegin( qs, flags, &h )) {
wprintf (L"Socket create, error 1 -%d\n", WSAGetLastError ());
//ExitProcess(2);
}
done = false;
while ( ! done ) {
if( SOCKET_ERROR == WSALookupServiceNext( h, flags, &qs_len, qs ) ) {
wprintf (L"Socket create, error 2 -%d\n", WSAGetLastError ());
int error = WSAGetLastError();
if( error == WSAEFAULT ) {
free(qs);
qs = (WSAQUERYSET*) malloc( qs_len );
} else if (error == WSA_E_NO_MORE ) {
done = true;
} else {
wprintf (L"Socket create, error 3- %d\n", WSAGetLastError ());
//ExitProcess(2);
}
} else {
port =
((SOCKADDR_BTH*)qs->lpcsaBuffer->RemoteAddr.lpSockaddr)->port;
}
}
free(qs);
WSALookupServiceEnd( h );
return port;
}
int _tmain(int argc, _TCHAR* argv[])
{
SOCKET sock;
SOCKADDR_BTH sa = { 0 };
int sa_len = sizeof(sa);
// initialize windows sockets
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 0 );
if( WSAStartup( wVersionRequested, &wsaData ) != 0 ) {
ExitProcess(2);
}
// parse the specified Bluetooth address
LPSTR abhi = "00:1d:fd:8e:21:8d";
int abhisize = sizeof (abhi);
if( abhisize < 2 ) {
fprintf(stderr, "usage: rfcomm-client <addr>\n"
"\n addr must be in the form (XX:XX:XX:XX:XX:XX)");
//ExitProcess(2);
}
if( SOCKET_ERROR == WSAStringToAddress( abhi, AF_BTH,
NULL, (LPSOCKADDR) &sa, &sa_len ) ) {
wprintf (L"String to address %d\n", WSAGetLastError ());
//ExitProcess(2);
}
// query it for the right port
// create the socket
sock = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
if( SOCKET_ERROR == sock ) {
wprintf (L"Socket create, error %d\n", WSAGetLastError ());
//ExitProcess(2);
}
// fill in the rest of the SOCKADDR_BTH struct
sa.port = SDPGetPort(abhi, (LPGUID) &OBEXFileTransfer);
//if( sa.port == 0 ) {
//ExitProcess(2);
//}
if( SOCKET_ERROR == connect( sock, (LPSOCKADDR) &sa, sa_len ) ) {
wprintf (L"Socket connect, error %d\n", WSAGetLastError ());
//ExitProcess(2);
}
send( sock, "hello!", 6, 0 );
closesocket(sock);
Sleep(10000);
return 0;
}
|
|
|
|
|
Ask this question in the Visual C++ forum. I don't see anything in here that's .NET related.
|
|
|
|
|
You should ask in the C++ forum like Dave said. There's nothing to do with .NET in your problem. Now, can you tell where the error is occuring, rather than just dumping the whole code. Makes it tough to isolate the problem.
"The clue train passed his station without stopping." - John Simmons / outlaw programmer
"Real programmers just throw a bunch of 1s and 0s at the computer to see what sticks" - Pete O'Hanlon
"Not only do you continue to babble nonsense, you can't even correctly remember the nonsense you babbled just minutes ago." - Rob Graham
|
|
|
|
|
Hi,
Is there any provision in dotnet architecture whereby if I simply create one CS file,
no matter what the application does (let any task execute), the control always ends at this CS file?
Thanks,
NetQuestions
|
|
|
|
|
Nope. Your "task" code would have to call this code directly if you wanted it to execute.
Or, if your code isn't dependant on any user interface elements at all, you could put it after the Application.Run(form) that starts your app.
|
|
|
|
|
Hi,
Could anybody help me in identifyieng free and opensource tool for source code versioning and bugtracking which can be seemlessly intigrated in Visual Studio 2008.
thanks in advance
If you have faith in the cause and
the means and in God, the hot
Sun will be cool for you.
|
|
|
|
|
|
Thankyou very much for the reply....
But please also tell me about the free bug tracking tool for dotnet applications.
If you have faith in the cause and
the means and in God, the hot
Sun will be cool for you.
|
|
|
|
|
|
Hi,
In an existing application, without touching the CS File for MDI or it's designer CS File,
how can I at run time, add a button to the MDI?
I am looking at writing a standalone CS file which should do the magic.
Thanks,
NetQuestions
|
|
|
|
|
Create the button:
Button myButton = new Button() Give it some text:
myButton.Text = "Press me!"; Assign an event handler:
myButton.Click += new EventHandler(myButton_Click); and add it to the form:
myForm.Controls.Add(myButton); Magic
Simon
|
|
|
|
|
Simon,
Suppose I have a form which has 5 buttons. On click of all the five buttons the MDI opens (all different tasks).
The code that you provided, if i write in a stand alone CS file, how do I get it implemented?
How is my CS file method invoked? I DO NOT WANT TO CALL IT EXPLICITLY ... that is a requirement!
|
|
|
|
|
This code would go in your form code, not normally a seperate CS file. The buttons show up on your form and call this code when the buttons are clicked.
NetQuestions wrote: I DO NOT WANT TO CALL IT EXPLICITLY ... that is a requirement!
This doesn't mean anything. I think you need to describe what your requirement is and why you have it as a requirement.
|
|
|
|
|
NetQuestions wrote: I DO NOT WANT TO CALL IT EXPLICITLY
Unfortunately, that is kind of how programming works. You can't just write a method and expect it to magically get called, you have to call it from somewhere.
How do you want it to get triggered?
You need to describe your requirement in more detail. What is it you are actually trying to do? I've shown you how to create and add a button to a form at runtime. All you have to do is decide how and when you want this code to be run.
Simon
|
|
|
|
|
Simon Stevens wrote: How do you want it to get triggered?
Telepathic software - been writing it for years, systems reads the users mind and invokes a thread in a different dimmension as required.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|