|
I have to call twice memory copy function every 33ms, now I do it with memcpy,but their cpu-cost is too high(two call cost 10ms,about %30 cpu-cost) to run program exactly .So I want to find a method to speed up mem copy .
Happy Gemini
|
|
|
|
|
memcpy is very optimized so there isn't much you can do to speed it up. However, if you ensured the memory was properly aligned, you could write some inline assembly to streamline the copy. At the very least you could measure how long it takes.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
i count the time every copy,it is near 5ms.
Happy Gemini
|
|
|
|
|
w_yufeng wrote:
cost 10ms,about %30 cpu-cost
What is %30 cpu cost? During the copy the cpu usage should be 100%. If it is not then for some reason the copy is being scheduled out of the cpu. Is there any hard disk activity during the copy?
John
|
|
|
|
|
Hard Disk actiity is not done by the processor rather by DMA.
may be 30% means 10ms out of 33ms or bad math.;)
|
|
|
|
|
I was thinking that the memory copy operation was causing page faults which would explain the low cpu usage. During a page fault the cpu would have to wait for the disk. But wait a minute 10ms would probably not be enough time to read even one sector on the disk...
John
|
|
|
|
|
It depends on your computer: it can be a MMX memcpy, a 3DNow memcpy or a SSE memcpy.
BTW, what are you doing, exactly?
A pointer switch every 10ms would be way more efficient. Why can't you do it?
Or are you doing video double buffering? In this case, you can do the memcpy only on video retrace, not every 10ms. Or you could do an AGP memory transfer, using DirectX or DirectVideo.
You won't be able to speed up this so much. The newest machines have a processor of 3.2Ghz and a FSB of 2x400 Mhz, that means your processor clock is 8 times your memories' clock; in simple words: memory is becoming slower and slower...
Perl combines all the worst aspects of C and Lisp: a billion different sublanguages in one monolithic executable. It combines the power of C with the readability of PostScript. -- Jamie Zawinski
|
|
|
|
|
Daniel Turini wrote:
A pointer switch every 10ms would be way more efficient. Why can't you do it?
thanks for reply.
my app is to grab the image with ccd.but since there is lots of noise,so we must reduce it.Yn = a*Xn + b*Xn_1 + c*Yn_1 is a iterative function.I must copy current Xn to Xn_1 and save current grabed image to Xn to use next time, but its cpu usage is so high that all denoise-process cpu usage cost nearly 96% .
Happy Gemini
|
|
|
|
|
w_yufeng wrote:
I must copy current Xn to Xn_1 and save current grabed image to Xn to use next time
This is what I don't understand. Why can't you just grab the ccd image directly to Xn?
Or does the CCD provide its own memory buffers? If this is the case, you're in trouble.
If the buffers are aligned on the OS 4,096 byte boundaries, you can try to use copy-on-write to duplicate physical memory pages as logical memory pages. This would be instantaneous, although I'm not sure if this is possible under Win32, but I think that by using VirtualAlloc/VirtualProtect you may be able to do it.
Perl combines all the worst aspects of C and Lisp: a billion different sublanguages in one monolithic executable. It combines the power of C with the readability of PostScript. -- Jamie Zawinski
|
|
|
|
|
because i need save the current raw data to Xn for the next call,while the current Xn is the image that grabed last time.
you can see code below:
//get current ccd buffer
pXn = m_pAcqExBuffers->GetImageAddress(nCurBufIndex);
//m_pRawXn is the raw image data grabed in last call
memcpy((void*)m_pXn_1, (void*)m_pRawXn, 2097152);
//get ccd buffer that had been processed in last call
nPreIndex = GetBufferIndex(nCurBufIndex, -1);
pYn_1 = m_pAcqExBuffers->GetImageAddress(nPreIndex);
//save the current raw data
memcpy((void*)m_pRawXn, (void *)pXn, 2097152);
//the image process function , the pXn(it is ccd buffer) is changed in the function
DeNoisePro((WORD *)pXn, (WORD *)m_pXn_1, (WORD *)pYn_1, 1024, 1024, 0, 6, 2);
Happy Gemini
|
|
|
|
|
I understood it, but I think you did not understand me: the problem is that with the call m_pAcqExBuffers->GetImageAddress(nCurBufIndex), the responsibility for allocating memory is in the m_pAcqExBuffers object. I don't know if this class can be modified by you, but imagine if you can call something like m_pAcqExBuffers->SetImageAddress(nCurBufIndex, m_pXn_1); This way you won't need to memcpy a single byte, as the ccd will put the data right were you want.
Even if this fails, if you implement a circular buffer and preserve it between calls, you'll need only 1 memcpy per pass: you don't need to call GetBufferIndex amd GetImageAddress on the last image, as it will be on the circular buffer already.
But you'll still facing problems, as you'll be reducing a memory transfer of 400MB/second to 200MB/second. 200MB/second is still a big figure, and if you change the code as I pointed, you'll be able to avoid it completely.
Perl combines all the worst aspects of C and Lisp: a billion different sublanguages in one monolithic executable. It combines the power of C with the readability of PostScript. -- Jamie Zawinski
|
|
|
|
|
Daniel Turini wrote:
as you'll be reducing a memory transfer of 400MB/second to 200MB/second. 200MB/second is still a big figure
i dont understand .
thanks.
as you said ,the ccd buffer is circular.u can see the denoise-func below:
Yn = a*Xn + b*Yn_1 + c*Xn_1
Yn is the image that is denoised and will be showed.Xn is the raw image that ccd grab currently.Xn_1 is the raw image that was grabed last time, Yn_1 is the image that was processed last time.that is ,ccd buffer carrys raw data before process and carrys ripe data after it.we must save copy raw data to Xn_1 and Xn .so that is why I must copy data twice.
I think that there maybe not have the better method to solve the problem.Now I just pin my hope on the update of the computer hardware.
thanks a lot
Happy Gemini
|
|
|
|
|
You could also try using physical memory...
AllocateUserPhysicalPages();
If you are using windows
|
|
|
|
|
I am programming a program to use modem dialup to retrieve data from SQL 2000 Server...
What would be a good solution for the connection between client pc and SQL 2000 server machine?
JW
DJ
|
|
|
|
|
well for fast access you need high speed connectivity, else the process will be very slow for large retrival.
|
|
|
|
|
thank you Mr.Prakash,
The concern is the project budget instead of the connection speed as data will not be that big.
You also are welcome to read the next message posted by me about this issue.
JW
DJ
|
|
|
|
|
Use dial up networking which is part of windows. Create an incomming connection on the server and a dial out connection on the client. You can have either side create a fixed ip address and get the client to autodial. If you want you can also use MS-CHAP which will give you an encrypted connection.
John
|
|
|
|
|
thanks John,
But the problem is after a dialup connection established between the PC Client and the DB Server, I could not login through The SQL Query Analyzer which resides on the PC side also.
Error message says the DB ( on the DB Server) does not exist or access denied.
COuld this be that the OS running on DB Server is Pro instead of win 2k Server? Any other ideas?
JW
DJ
|
|
|
|
|
Did you try to connect to the database using the ip address instead of the machine name?
John
|
|
|
|
|
I tried the IP address in SQL QUERY Analyzer. It did not work either.
I am trying to access using code:
sDSN = "Provider=sqloledb;" &_
"Data Source=TEST\SEAN;" &_
"Initial Catalog=test;" & _
"User Id=sa;" &_
"Password=password"
\
thanks
DJ
|
|
|
|
|
Thanks a lots.
The problem was caused by some OS modules corrupted in Win 2k.
I changed to another SQL server on a third machine, now I can access via SQL Query Analyzer and my program.
DJ
|
|
|
|
|
I have an SQL Server 2k (personal edition) running on Windows 2000 Pro for testing.
I tried to connect from other PC running SQL server to this databse. However,
from SQL Query Analyzer on the local PC, I could not find the database once I clicked on the ... which is right to the SQL Sever: text box.
The connection between the PC and the Database machine is modem dialup. From either side, I can ping to each other without any problem.
Moreover, once I connected my PC to the intranet, I can access/login to any SQl server database which is within the intranet environment.
ANy help are greatly appreciated.
JW
DJ
|
|
|
|
|
What exactly isthe question??? 
|
|
|
|
|
Sorry I forgot the problem description itself.
The problem is that after the PC client and DB Server (currently SQL 2000 sever running on WIndows 2k Pro) were connected via a dialin service, from the PC site I can not see the DB on the DB Server, nor could I login to the SQL residing on DB Server of course.
ANy idea, again?
JW
DJ
|
|
|
|
|
Ok, I think i know the problem now,
You can access the DB when you are connected to the intranet but now able to access it via dial in. That is because the firewall of the intarnet is not allowing to make connection from outside the intranet.
This is to prevent hackers/viruses to connect to the network. You need to talk to the network administrator of your organization and how he can allow access to the DB only from outside the intranet.
|
|
|
|