Search Results

Search found 27244 results on 1090 pages for 'old computer'.

Page 211/1090 | < Previous Page | 207 208 209 210 211 212 213 214 215 216 217 218  | Next Page >

  • Networking multiple computers to one brain in Java

    - by Morpheous
    Hello, I was wondering which libraries or API's would be useful in this. what im aiming for is to be able to type a command into a prompt and then specify which computer(out of all of them that are networked together) to execute that command on. the second part is i want to be able to see that command execute and the result on the computer that was specified. for example if i enter "firefox www.google.com, desktop2" i want to be able to see the window open on the monitor of that computer. Do you understand what im trying to do? any help is appreciated. Thanks, Morpheous

    Read the article

  • Problem with running c# application on another PC

    - by draghia-aurelian
    I wrote a Windows Form Application in C# and it works well for my computer. But on another PC, an error occurs when i try to do some stuff. code 1 private void rUNToolStripMenuItem_Click(object sender, EventArgs e) { MessageBox.Show("I'm in rUNToolStripMenuItem_Click!"); ... } code 2 private void dataPositionToolStripMenuItem_Click(object sender, EventArgs e) { MessageBox.Show("I'm in dataPositionToolStripMenuItem_Click!"); ... } Running on my computer: code1: MessageBox appears! code2: MessageBox appears! Running on another computer: code1: MessageBox doesn't appear and the error happens! code2: MessageBox appears! The error is: Method not found: "Void Microsoft.CSharp.RuntimeBinder.CSharpGetMemberBider..ctor(System.String.System.Type, System.Collections.Generic.IEnumerable'1)'. This is the PrintScreen with error: Please help me to solve the problem!

    Read the article

  • How do I sync Dreamweaver site definitions across 2 computers?

    - by baritoneuk
    I use Dreamweaver on my laptop and Desktop PC and frequently change between them. I keep all my sites synced using Syncplicity (similar to Dropbox, which indecently I also use) I want my site definitions to be synced across the two computers. If I add a new site on one computer I want it to appear on the other one. I know I can export all sites on one computer and then get Syncplicity to sync the files to the other computer at which point I can import them. However this relies on me remembering to do this each time I add a new site, and it's also quite time consuming. As far as I can tell, Dreamweaver (at least upto CS4- not sure about CS5) stupidly stores the site definitions in the registry. I really don't know why they do this- if they stored it in xml files then I could easily sync the information. Does anyone know if what I am asking is possible?

    Read the article

  • iPhone tethering app source

    - by jamone
    I know there are a few apps that allow a jail broken iPhone to tether over WiFi to a computer so the computer can use the iPhone's 3G. What I want to know is if anyone knows of any open source apps that do this, or partial code to handle the majority of this that I could make in to a minimal app? I don't want to jail break since I do official development, but would like to be able to compile and sideload an app on my personal phone to do this. Even without jail broken privileges an app could use an existing wifi connection (adhoc created by the computer) to share its 3G.

    Read the article

  • Subversion post-commit hook to sync rep with FTP server ( for a website )

    - by Brett
    I've installed a repository on my computer locally. What I'm trying to do is be able to work on a website locally on my computer and see changes using something like MAMP. When I commit a change though I'd like it to sync my repo with the live website source files on a remote FTP server. I've done a bit of digging and I know that people keep saying to use a post-commit hook but I'm not sure how to configure it or even how to install it locally. Also i'm not sure if it's possible to do from my computer to an FTP. Could someone be a huge help and walk me through how to do this I've been trying for hours to figure out how to do it. thanks so much.

    Read the article

  • Is there a technical way to speed up a general program above current PC speed limit?

    - by Maksee
    Let's imagine I developed a Windows console application implementing some algorithm calculating something. Let's say it doesn't use any threads, just straightforward linear approach with ifs, loops and so on. Is there any technical way to make if run it 100x times faster than on the most advanced current PC? For example one of the way would be to run it on a super computer that emulates i386 faster than any of the existing PCs. But in this case the question what computer and does it really have ability to emulate Windows. In other words, is there real examples of such approach? Although in general it looks useless, but if there is a way, one could develop some program on his general home computer and pay for running it much faster on some other hardware. I suppose that this question could be asked on superuser.com, but since there are possible specific with such things as assembler instructions or threads, I thought that stackoverflow.com is better

    Read the article

  • Generation of .tlb Files in Windows 7 Pro 32-bit

    - by aF
    I have a C++ DLL that imports a .tlb file generated in a C# project. The C++ DLL is a wrapper DLL containing functions that call the corresponding C# functions. When I call the C++ functions on the computer that I built the projects, all works well. But when I copy the DLL's and generated tlb's to another computer with the same exact version of Windows and installed programs andI call the C++ functions, it breaks with a COM error. However, after recompiling the projects on the new computer, everything works again. I already checked the "Work on All Computers" for both projects but this keeps happening. What else do I need to do for the DLL's to work on all computers?

    Read the article

  • WCF: connecting to service over internet times out

    - by Shaul
    Still on the WCF learning curve: I've set up a self-hosted WCF Service (WSDualHttpBinding), which works fine on my own computer, which resides behind a firewall. If I run the client on my own computer, everything works great. Now I installed the client on a computer outside my network, and I'm trying to access the service via a dynamic DNS, like so: http://mydomain.dyndns.org:8000/MyService. My port forwarding issues were taken care of in a previous question; I can now see the service is up in my browser. But now when I try to run the client on the other machine, I get the following error message: "The open operation did not complete within the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout." I have disabled security on the service, so that's not it. What else might be preventing the connection from happening?

    Read the article

  • RUNNING PHP IN NETBEANS

    - by user216112
    i have netbeans 6.8 with all bundle faetures. now i m running my php file Binary Search h1 {color: blue} Computer guess number by using binary search Input your hidden number: (1-99) Here; } else { if ($max_num==-1 && $min_num==-1) { $max_num = 100; $min_num = 0; $result_num = $hid_num; } else { if ($comparision == "bigger") { $min_num = $guess_num; } else if ($comparision == "smaller") { $max_num = $guess_num; } } $guess_num = ($max_num + $min_num)/2; setType($guess_num,"integer"); print "Computer guess $guess_num "; if ($guess_num == $result_num) { $flag_num = -1; } if ($flag_num == -1) { print Congratulation, Computer win " Here; } else { print Your intruction: Bigger Smaller Here; } } ? but the erreor coming in the "HTTP 404 NOT FOUND" I THINK SERVER HAS BEEN NOT BEEN SET.SO WHAT SHOULD I DO TO RUN IT

    Read the article

  • Can I tell Borland C++ Builder to copy a file somewhere else after it is built?

    - by MrVimes
    I have two computers. One is intended to be left 'free' for high-performance activities (such as playing games) The other is my 'all purpose' computer where I install all the apps I use for creating things, and so on. On the second computer I use Codegear C++ Builder to work on an app that I use on the first computer. If I have BCB compile to comp 1 it is hopeless. It becomes unresponsive. It compiles locally very quickly. So what I do is compile locally and then copy the exe to the other machine. Well, I'm all for streamlining processes, so I want a way to compile on PC2 and use on PC1 without any intermediate steps. So is it possible to have BCB do the compiling on PC2 and create a local exe file, then copy the file to PC 1?

    Read the article

  • I love programming but i also want to learn hardware. [closed]

    - by user167082
    I like programming so much, i did it since i was 10, and i believe that studying computer science will make a lot of money as well as i love it. However I also want to learn hardware. I don't only want to do programming all the time without knowing the architecture of device that i program. I asked my teacher, and she said that if I get into computer science, i won't learn anything about hardware, is it true?(She graduated from u-dub) In the other hand, my math teacher told me to get into electrical engineering, since it also contain programming. The thing is that i want to emphasize my study to programming while learning some about hardware. What is major that suits me the best? Can i take some hardware courses if I get into computer science major? Thanks a lot.

    Read the article

  • interuption while running php file

    - by user216112
    this is my code in php bt its not working problerly as required..the output is not according to this.. i m trying to run this in wamp server. plz help /* Binary Search h1 {color: blue} Computer guess number by using binary search Input your hidden number: (1-99) Here; } else { if ($max_num==-1 && $min_num==-1) { $max_num = 100; $min_num = 0; $result_num = $hid_num; } else { if ($comparision == "bigger") { $min_num = $guess_num; } else if ($comparision == "smaller") { $max_num = $guess_num; } } $guess_num = ($max_num + $min_num)/2; setType($guess_num,"integer"); print "Computer guess $guess_num "; if ($guess_num == $result_num) { $flag_num = -1; } if ($flag_num == -1) { print Congratulation, Computer win " Here; } else { print Your intruction: Bigger Smaller Here; } } ? */

    Read the article

  • Compile Qt Project To Run On A Linux System

    - by ForgiveMeI'mAN00b
    I have a Qt project. It uses the cross platform libraries SDL, OpenGL and FLTK. I want to be able to compile the project so that it can run on a Linux computer. I'm looking at a bunch of articles I have seen so far two ways to do this. Use a cross compiler, which seems to me a rather complicated thing to setup and compile with, or, the other options, is to compile the project simply on a Linux computer, simply the Linux version of Qt creator/SDK. My question is, If I have a Qt project that uses only cross platform libraries, then is creating a Windows version easy as compiling it in Qt/Windows, and creating the Linux version as easy as doing it in Qt/Linux? PS. Please don't ask/complain about why I didn't just try to see if it works myself, I don't have any Linux OS's installed on my computer right now, and I don't want to risk going into the trouble of installing a whole new OS just to have it not work in the end.

    Read the article

  • How can I pass Arguments to a C++ program started by the Registry?

    - by Y_Y
    Hello, I'm creating a Win32 program that will be executed every time the computer turns on. I manage to do this by adding the .exe path into the registry. The problem is; I want to make the program appear minimized in the system tray when the computer is turned on but if I double click it [after the computer turns on and the program is not currently running] the program should appear on its normal [maximized] size. Question, I was thinking on whether is was possible to pass an argument to the program when the program is executed from the registry. Is this possible? If yes/no, how would I manage to do this? (Using windows XP) Thanks.

    Read the article

  • extension file "curl" is must be loaded

    - by Sharvan
    Using XAMPP 1.6.7 I installed the community version of Magento. But there seems to be a problem. I am getting the error message 'extension file "curl" is must be loaded'. In another computer, everything seems fine. (the other computer) intel(R) Pentium(R) Dual CPU, E2140 @ 1.60Hz, 1.60 GHz. 504 MB of RAM and XP professional 2002 sp2 My computer is less powerful (Inet Pentium 4 1.6 GHz. with sp2.) Please help me, thanks.

    Read the article

  • jQuery .ajax request failing

    - by user1644808
    I currently have a jQuery ajax request set up like this $(document).ready( function() { $.ajax({ url : "http://www.my-computer.com:51000/getJson", cache : false, dataType: "json", success : renderPage, error: handleError }) }); If I manually naviate to http://www.my-computer.com:51000/getJson, I see it returns a json string correctly, but with the above request, I always fall into "handleError" method, with textStatus "error" and not much helpful information. Can anyone help? Thanks! EDIT: sorry about the my-computer domain. this stackoverflow submission won't let me input localhost, so I put in an arbitrary domain instead. I've tried firebug, but had no luck in getting the json back.

    Read the article

  • absolute audio synchronization

    - by user1780526
    I would like to synchronize my computer with an external camcorder recording so that I can know exactly (to the millisecond) when certain recored events happen with respect to other sensors logged by the computer. One idea is to playback short sound pulses or chirps every second from the computer that get picked up by the microphone on the camcorder. But the accuracy of a simple cron job playing a sound clip is not precise enough. I was thinking of using something like gstreamer, but how does one get it to playback a clip at precisely a certain time according to the system clock?

    Read the article

  • Using regular expressions with Dojo data.fetch?

    - by Dfowj
    I'm trying to use the below code to fetch a regular expression like this /[computer]{3,8}/(what i think is any words containing the letters in computer ranging from 3 to 8 letters long) from a database (which i know is being loaded correctly). When i fetch, i get 10 results, all the same word... "Adenauer" var base = "computer"; var baseRE = '/[' + base + ']{' + this.minLength + ',' + base.length + '}/'; this.dict.fetch({query: {word:baseRE}, onComplete: onLoadWords, onError: function(err) { console.log(err); }}); Any ideas what im doing wrong?

    Read the article

  • Get machine name from Active Directory

    - by Stephen Murby
    I have performed an "LDAP://" query to get a list of computers within a specified OU, my issue is not being able to collect just the computer "name" or even "cn". DirectoryEntry toShutdown = new DirectoryEntry("LDAP://" + comboBox1.Text.ToString()); DirectorySearcher machineSearch = new DirectorySearcher(toShutdown); //machineSearch.Filter = "(objectCatergory=computer)"; machineSearch.Filter = "(objectClass=computer)"; machineSearch.SearchScope = SearchScope.Subtree; machineSearch.PropertiesToLoad.Add("name"); SearchResultCollection allMachinesCollected = machineSearch.FindAll(); Methods myMethods = new Methods(); string pcName; foreach (SearchResult oneMachine in allMachinesCollected) { //pcName = oneMachine.Properties.PropertyNames.ToString(); pcName = oneMachine.Properties["name"].ToString(); MessageBox.Show(pcName); } Help much appreciated.

    Read the article

  • Help with my application please! Can’t open image(s) with error: External component has thrown an ex

    - by Brandon
    I have an application written in C# I believe and it adds images to a SQL Server 2005 Database. It requires .NET 3.5 to be installed on my computer. I installed .NET 3.5 and setup a database. It runs fine but then once it gets to image 100 when running on one computer, It stops and gives me this error: Can't open image(s) with error: External component has thrown an exception.... When I run the program on my own computer I am able to reach 300 images but then it stops after 300 images and gives me Can't open image(s) with error: External component has thrown an exception.... error once again. please help!

    Read the article

  • Beginner's Language app

    - by Eiseldora
    Hi I'm a techie with no programing experience. I know html and css, but I'd like to someday be able to make an app for my phone (I have an android) and possibly mobile websites. I made learning a programing language and creating a mobile app a goal for my job, and now my boss would like me to pick a programing language to learn. I found a free open course from MIT (http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-00-introduction-to-computer-science-and-programming-fall-2008/) called introduction to computer science. In the course they teach python, but more importantly it seems they teach how to think like a programmer. When I told my boss about the free online course she didn't think that Python was an appropriate language for me to learn. She'd like me to learn a language that is more similar to one used to make Phone apps. Does anyone out there know a better language for me to pick up that would be similar to Android or iPhone's App language. Thank you

    Read the article

  • how to recieve mail using python>

    - by user600950
    Hey everyone, I am trying to make a program on my computer at home that will constantly check a certain gmail address. The purpose being the only email this adress recieves is from me. I would just like to be able to 1.Check for mail 2.Download mail(presumably to a string, though a file is acceptable) and 3. delete the mail from the web server but keep it on my computer. Thta is all i need to know right now, however my long term goal is to set up kind of a remote terminal over email, so that wherever i have email i have a certain amount of control over my computer.

    Read the article

  • Windows Phone appointment task

    - by Dennis Vroegop
    Originally posted on: http://geekswithblogs.net/dvroegop/archive/2014/08/10/windows-phone-appointment-task.aspxI am currently working on a new version of my AgeInDays app for Windows Phone. This app calculates how old you are in days (or weeks, depending on your preferences). The inspiration for this app came from my father, who once told me he proposed to my mother when she was 1000 weeks old. That left me wondering: how old in weeks or days am I? And being the geek I am, I wrote an app for it. If you have a Windows Phone, you can find it at http://www.windowsphone.com/en-in/store/app/age-in-days/7ed03603-0e00-4214-ad04-ce56773e5dab A new version of the app was published quite quickly, adding the possibility to mark a date in your agenda when you would have reached a certain age. Of course the logic behind this if extremely simple. Just take a DateTime, populate it with the given date from the DatePicker, then call AddDays(numDays) and voila, you have the date. Now all I had to do was implement a way to store this in the users calendar so he would get a reminder when that date occurred. Luckily, the Windows Phone SDK makes that extremely simple: public void PublishTask(DateTime occuranceDate, string message) { var task = new SaveAppointmentTask() { StartTime = occuranceDate, EndTime = occuranceDate, Subject = message, Location = string.Empty, IsAllDayEvent = true, Reminder = Reminder.None, AppointmentStatus = AppointmentStatus.Free };   task.Show(); }  And that's it. Whenever I call the PublishTask Method an appointment will be made and put in the calendar. Well, not exactly: a template will be made for that appointment and the user will see that template, giving him the option to either discard or save the reminder. The user can also make changes before submitting this to the calendar: it would be useful to be able to change the text in the agenda and that's exactly what this allows you to do. Now, see at the bottom of the screen the option "Occurs". This tiny field is what this post is about. You cannot set it from the code. I want to be able to have repeating items in my agenda. Say for instance you're counting down to a certain date, I want to be able to give you that option as well. However, I cannot. The field "occurs" is not part of the Task you create in code. Of course, you could create a whole series of events yourself. Have the "Occurs" field in your own user interface and make all the appointments. But that's not the same. First, the system doesn't recognize them as part of a series. That means if you want to change the text later on on one of the occurrences it will not ask you if you want to open this one or the whole series. More important however, is that the user has to acknowledge each and every single occurrence and save that into the agenda. Now, I understand why they implemented the system in such a way that the user has to approve an entry. You don't want apps to automatically fill your agenda with messages such as "Remember to pay for my app!". But why not include the "Occurs" option? The user can still opt out if they see this happening. I hope an update will fix this soon. But for now: you just have to countdown to your birthday yourself. My app won't support this.

    Read the article

  • Wipe, Delete, and Securely Destroy Your Hard Drive’s Data the Easy Way

    - by The Geek
    Giving a computer to somebody else? Maybe you’re putting it out on Craigslist to sell to a stranger—either way, you’ll want to make sure that your drive is completely wiped, scrubbed, and clean of any personal data. Here’s the easy way to do it. If you only have access to an Ubuntu Live CD or thumb drive, you can actually use that instead if you prefer, and we’ve got you covered with a full guide to securely wiping your PC’s hard drive. Otherwise, keep reading. Wipe the Drive with DBAN Darik’s Boot and Nuke CD is the easiest way to permanently and totally destroy every bit of personal information on that drive—nobody is going to recover a thing once this is done. The first thing you’ll need to do is download a copy of the ISO image, and then burn it to a blank CD with something really useful like Imgburn. Just choose Burn image to Disc at the start screen, select the little file icon, grab the downloaded ISO, and then go. If you need a little more help, we’ve got you covered with a beginner’s guide to burning an ISO image. Once you’re done, stick the disc into the drive, start the PC up, and then once you boot to the DBAN prompt you’ll see a menu. You can pretty much ignore everything on here, and just type… autonuke And there you are, your disk is now being securely wiped. Once it’s all done, you can remove the CD, and then either pack the PC up to sell, or re-install Windows on there if you feel like it. More Advanced Method If you’re really paranoid, want to run a different type of wipe, or just like fiddling with the options, you can choose F3 or hit Enter at the prompt to head to the advanced selection screen. Here you can choose exactly which drive to wipe, or hit the M key to change the method. You’ll be able to choose between a bunch of different wipe options. The Quick Erase is all you really need though.   So there you are, easy PC wiping in one package. What about you? Do you make sure to wipe your old PCs before giving them away? Personally I’ve always just yanked out the hard drives before I got rid of an old PC, but that’s just me. Download DBAN from dban.org Similar Articles Productive Geek Tips Use an Ubuntu Live CD to Securely Wipe Your PC’s Hard DriveHow to Dispose of Old Computers ResponsiblyHow To Delete a VHD in Windows 7Speed up External USB Hard Drives in Windows VistaSpeed Up SATA Hard Drives in Windows Vista TouchFreeze Alternative in AutoHotkey The Icy Undertow Desktop Windows Home Server – Backup to LAN The Clear & Clean Desktop Use This Bookmarklet to Easily Get Albums Use AutoHotkey to Assign a Hotkey to a Specific Window Latest Software Reviews Tinyhacker Random Tips DVDFab 6 Revo Uninstaller Pro Registry Mechanic 9 for Windows PC Tools Internet Security Suite 2010 Follow Finder Finds You Twitter Users To Follow Combine MP3 Files Easily QuicklyCode Provides Cheatsheets & Other Programming Stuff Download Free MP3s from Amazon Awe inspiring, inter-galactic theme (Win 7) Case Study – How to Optimize Popular Wordpress Sites

    Read the article

  • How John Got 15x Improvement Without Really Trying

    - by rchrd
    The following article was published on a Sun Microsystems website a number of years ago by John Feo. It is still useful and worth preserving. So I'm republishing it here.  How I Got 15x Improvement Without Really Trying John Feo, Sun Microsystems Taking ten "personal" program codes used in scientific and engineering research, the author was able to get from 2 to 15 times performance improvement easily by applying some simple general optimization techniques. Introduction Scientific research based on computer simulation depends on the simulation for advancement. The research can advance only as fast as the computational codes can execute. The codes' efficiency determines both the rate and quality of results. In the same amount of time, a faster program can generate more results and can carry out a more detailed simulation of physical phenomena than a slower program. Highly optimized programs help science advance quickly and insure that monies supporting scientific research are used as effectively as possible. Scientific computer codes divide into three broad categories: ISV, community, and personal. ISV codes are large, mature production codes developed and sold commercially. The codes improve slowly over time both in methods and capabilities, and they are well tuned for most vendor platforms. Since the codes are mature and complex, there are few opportunities to improve their performance solely through code optimization. Improvements of 10% to 15% are typical. Examples of ISV codes are DYNA3D, Gaussian, and Nastran. Community codes are non-commercial production codes used by a particular research field. Generally, they are developed and distributed by a single academic or research institution with assistance from the community. Most users just run the codes, but some develop new methods and extensions that feed back into the general release. The codes are available on most vendor platforms. Since these codes are younger than ISV codes, there are more opportunities to optimize the source code. Improvements of 50% are not unusual. Examples of community codes are AMBER, CHARM, BLAST, and FASTA. Personal codes are those written by single users or small research groups for their own use. These codes are not distributed, but may be passed from professor-to-student or student-to-student over several years. They form the primordial ocean of applications from which community and ISV codes emerge. Government research grants pay for the development of most personal codes. This paper reports on the nature and performance of this class of codes. Over the last year, I have looked at over two dozen personal codes from more than a dozen research institutions. The codes cover a variety of scientific fields, including astronomy, atmospheric sciences, bioinformatics, biology, chemistry, geology, and physics. The sources range from a few hundred lines to more than ten thousand lines, and are written in Fortran, Fortran 90, C, and C++. For the most part, the codes are modular, documented, and written in a clear, straightforward manner. They do not use complex language features, advanced data structures, programming tricks, or libraries. I had little trouble understanding what the codes did or how data structures were used. Most came with a makefile. Surprisingly, only one of the applications is parallel. All developers have access to parallel machines, so availability is not an issue. Several tried to parallelize their applications, but stopped after encountering difficulties. Lack of education and a perception that parallelism is difficult prevented most from trying. I parallelized several of the codes using OpenMP, and did not judge any of the codes as difficult to parallelize. Even more surprising than the lack of parallelism is the inefficiency of the codes. I was able to get large improvements in performance in a matter of a few days applying simple optimization techniques. Table 1 lists ten representative codes [names and affiliation are omitted to preserve anonymity]. Improvements on one processor range from 2x to 15.5x with a simple average of 4.75x. I did not use sophisticated performance tools or drill deep into the program's execution character as one would do when tuning ISV or community codes. Using only a profiler and source line timers, I identified inefficient sections of code and improved their performance by inspection. The changes were at a high level. I am sure there is another factor of 2 or 3 in each code, and more if the codes are parallelized. The study’s results show that personal scientific codes are running many times slower than they should and that the problem is pervasive. Computational scientists are not sloppy programmers; however, few are trained in the art of computer programming or code optimization. I found that most have a working knowledge of some programming language and standard software engineering practices; but they do not know, or think about, how to make their programs run faster. They simply do not know the standard techniques used to make codes run faster. In fact, they do not even perceive that such techniques exist. The case studies described in this paper show that applying simple, well known techniques can significantly increase the performance of personal codes. It is important that the scientific community and the Government agencies that support scientific research find ways to better educate academic scientific programmers. The inefficiency of their codes is so bad that it is retarding both the quality and progress of scientific research. # cacheperformance redundantoperations loopstructures performanceimprovement 1 x x 15.5 2 x 2.8 3 x x 2.5 4 x 2.1 5 x x 2.0 6 x 5.0 7 x 5.8 8 x 6.3 9 2.2 10 x x 3.3 Table 1 — Area of improvement and performance gains of 10 codes The remainder of the paper is organized as follows: sections 2, 3, and 4 discuss the three most common sources of inefficiencies in the codes studied. These are cache performance, redundant operations, and loop structures. Each section includes several examples. The last section summaries the work and suggests a possible solution to the issues raised. Optimizing cache performance Commodity microprocessor systems use caches to increase memory bandwidth and reduce memory latencies. Typical latencies from processor to L1, L2, local, and remote memory are 3, 10, 50, and 200 cycles, respectively. Moreover, bandwidth falls off dramatically as memory distances increase. Programs that do not use cache effectively run many times slower than programs that do. When optimizing for cache, the biggest performance gains are achieved by accessing data in cache order and reusing data to amortize the overhead of cache misses. Secondary considerations are prefetching, associativity, and replacement; however, the understanding and analysis required to optimize for the latter are probably beyond the capabilities of the non-expert. Much can be gained simply by accessing data in the correct order and maximizing data reuse. 6 out of the 10 codes studied here benefited from such high level optimizations. Array Accesses The most important cache optimization is the most basic: accessing Fortran array elements in column order and C array elements in row order. Four of the ten codes—1, 2, 4, and 10—got it wrong. Compilers will restructure nested loops to optimize cache performance, but may not do so if the loop structure is too complex, or the loop body includes conditionals, complex addressing, or function calls. In code 1, the compiler failed to invert a key loop because of complex addressing do I = 0, 1010, delta_x IM = I - delta_x IP = I + delta_x do J = 5, 995, delta_x JM = J - delta_x JP = J + delta_x T1 = CA1(IP, J) + CA1(I, JP) T2 = CA1(IM, J) + CA1(I, JM) S1 = T1 + T2 - 4 * CA1(I, J) CA(I, J) = CA1(I, J) + D * S1 end do end do In code 2, the culprit is conditionals do I = 1, N do J = 1, N If (IFLAG(I,J) .EQ. 0) then T1 = Value(I, J-1) T2 = Value(I-1, J) T3 = Value(I, J) T4 = Value(I+1, J) T5 = Value(I, J+1) Value(I,J) = 0.25 * (T1 + T2 + T5 + T4) Delta = ABS(T3 - Value(I,J)) If (Delta .GT. MaxDelta) MaxDelta = Delta endif enddo enddo I fixed both programs by inverting the loops by hand. Code 10 has three-dimensional arrays and triply nested loops. The structure of the most computationally intensive loops is too complex to invert automatically or by hand. The only practical solution is to transpose the arrays so that the dimension accessed by the innermost loop is in cache order. The arrays can be transposed at construction or prior to entering a computationally intensive section of code. The former requires all array references to be modified, while the latter is cost effective only if the cost of the transpose is amortized over many accesses. I used the second approach to optimize code 10. Code 5 has four-dimensional arrays and loops are nested four deep. For all of the reasons cited above the compiler is not able to restructure three key loops. Assume C arrays and let the four dimensions of the arrays be i, j, k, and l. In the original code, the index structure of the three loops is L1: for i L2: for i L3: for i for l for l for j for k for j for k for j for k for l So only L3 accesses array elements in cache order. L1 is a very complex loop—much too complex to invert. I brought the loop into cache alignment by transposing the second and fourth dimensions of the arrays. Since the code uses a macro to compute all array indexes, I effected the transpose at construction and changed the macro appropriately. The dimensions of the new arrays are now: i, l, k, and j. L3 is a simple loop and easily inverted. L2 has a loop-carried scalar dependence in k. By promoting the scalar name that carries the dependence to an array, I was able to invert the third and fourth subloops aligning the loop with cache. Code 5 is by far the most difficult of the four codes to optimize for array accesses; but the knowledge required to fix the problems is no more than that required for the other codes. I would judge this code at the limits of, but not beyond, the capabilities of appropriately trained computational scientists. Array Strides When a cache miss occurs, a line (64 bytes) rather than just one word is loaded into the cache. If data is accessed stride 1, than the cost of the miss is amortized over 8 words. Any stride other than one reduces the cost savings. Two of the ten codes studied suffered from non-unit strides. The codes represent two important classes of "strided" codes. Code 1 employs a multi-grid algorithm to reduce time to convergence. The grids are every tenth, fifth, second, and unit element. Since time to convergence is inversely proportional to the distance between elements, coarse grids converge quickly providing good starting values for finer grids. The better starting values further reduce the time to convergence. The downside is that grids of every nth element, n > 1, introduce non-unit strides into the computation. In the original code, much of the savings of the multi-grid algorithm were lost due to this problem. I eliminated the problem by compressing (copying) coarse grids into continuous memory, and rewriting the computation as a function of the compressed grid. On convergence, I copied the final values of the compressed grid back to the original grid. The savings gained from unit stride access of the compressed grid more than paid for the cost of copying. Using compressed grids, the loop from code 1 included in the previous section becomes do j = 1, GZ do i = 1, GZ T1 = CA(i+0, j-1) + CA(i-1, j+0) T4 = CA1(i+1, j+0) + CA1(i+0, j+1) S1 = T1 + T4 - 4 * CA1(i+0, j+0) CA(i+0, j+0) = CA1(i+0, j+0) + DD * S1 enddo enddo where CA and CA1 are compressed arrays of size GZ. Code 7 traverses a list of objects selecting objects for later processing. The labels of the selected objects are stored in an array. The selection step has unit stride, but the processing steps have irregular stride. A fix is to save the parameters of the selected objects in temporary arrays as they are selected, and pass the temporary arrays to the processing functions. The fix is practical if the same parameters are used in selection as in processing, or if processing comprises a series of distinct steps which use overlapping subsets of the parameters. Both conditions are true for code 7, so I achieved significant improvement by copying parameters to temporary arrays during selection. Data reuse In the previous sections, we optimized for spatial locality. It is also important to optimize for temporal locality. Once read, a datum should be used as much as possible before it is forced from cache. Loop fusion and loop unrolling are two techniques that increase temporal locality. Unfortunately, both techniques increase register pressure—as loop bodies become larger, the number of registers required to hold temporary values grows. Once register spilling occurs, any gains evaporate quickly. For multiprocessors with small register sets or small caches, the sweet spot can be very small. In the ten codes presented here, I found no opportunities for loop fusion and only two opportunities for loop unrolling (codes 1 and 3). In code 1, unrolling the outer and inner loop one iteration increases the number of result values computed by the loop body from 1 to 4, do J = 1, GZ-2, 2 do I = 1, GZ-2, 2 T1 = CA1(i+0, j-1) + CA1(i-1, j+0) T2 = CA1(i+1, j-1) + CA1(i+0, j+0) T3 = CA1(i+0, j+0) + CA1(i-1, j+1) T4 = CA1(i+1, j+0) + CA1(i+0, j+1) T5 = CA1(i+2, j+0) + CA1(i+1, j+1) T6 = CA1(i+1, j+1) + CA1(i+0, j+2) T7 = CA1(i+2, j+1) + CA1(i+1, j+2) S1 = T1 + T4 - 4 * CA1(i+0, j+0) S2 = T2 + T5 - 4 * CA1(i+1, j+0) S3 = T3 + T6 - 4 * CA1(i+0, j+1) S4 = T4 + T7 - 4 * CA1(i+1, j+1) CA(i+0, j+0) = CA1(i+0, j+0) + DD * S1 CA(i+1, j+0) = CA1(i+1, j+0) + DD * S2 CA(i+0, j+1) = CA1(i+0, j+1) + DD * S3 CA(i+1, j+1) = CA1(i+1, j+1) + DD * S4 enddo enddo The loop body executes 12 reads, whereas as the rolled loop shown in the previous section executes 20 reads to compute the same four values. In code 3, two loops are unrolled 8 times and one loop is unrolled 4 times. Here is the before for (k = 0; k < NK[u]; k++) { sum = 0.0; for (y = 0; y < NY; y++) { sum += W[y][u][k] * delta[y]; } backprop[i++]=sum; } and after code for (k = 0; k < KK - 8; k+=8) { sum0 = 0.0; sum1 = 0.0; sum2 = 0.0; sum3 = 0.0; sum4 = 0.0; sum5 = 0.0; sum6 = 0.0; sum7 = 0.0; for (y = 0; y < NY; y++) { sum0 += W[y][0][k+0] * delta[y]; sum1 += W[y][0][k+1] * delta[y]; sum2 += W[y][0][k+2] * delta[y]; sum3 += W[y][0][k+3] * delta[y]; sum4 += W[y][0][k+4] * delta[y]; sum5 += W[y][0][k+5] * delta[y]; sum6 += W[y][0][k+6] * delta[y]; sum7 += W[y][0][k+7] * delta[y]; } backprop[k+0] = sum0; backprop[k+1] = sum1; backprop[k+2] = sum2; backprop[k+3] = sum3; backprop[k+4] = sum4; backprop[k+5] = sum5; backprop[k+6] = sum6; backprop[k+7] = sum7; } for one of the loops unrolled 8 times. Optimizing for temporal locality is the most difficult optimization considered in this paper. The concepts are not difficult, but the sweet spot is small. Identifying where the program can benefit from loop unrolling or loop fusion is not trivial. Moreover, it takes some effort to get it right. Still, educating scientific programmers about temporal locality and teaching them how to optimize for it will pay dividends. Reducing instruction count Execution time is a function of instruction count. Reduce the count and you usually reduce the time. The best solution is to use a more efficient algorithm; that is, an algorithm whose order of complexity is smaller, that converges quicker, or is more accurate. Optimizing source code without changing the algorithm yields smaller, but still significant, gains. This paper considers only the latter because the intent is to study how much better codes can run if written by programmers schooled in basic code optimization techniques. The ten codes studied benefited from three types of "instruction reducing" optimizations. The two most prevalent were hoisting invariant memory and data operations out of inner loops. The third was eliminating unnecessary data copying. The nature of these inefficiencies is language dependent. Memory operations The semantics of C make it difficult for the compiler to determine all the invariant memory operations in a loop. The problem is particularly acute for loops in functions since the compiler may not know the values of the function's parameters at every call site when compiling the function. Most compilers support pragmas to help resolve ambiguities; however, these pragmas are not comprehensive and there is no standard syntax. To guarantee that invariant memory operations are not executed repetitively, the user has little choice but to hoist the operations by hand. The problem is not as severe in Fortran programs because in the absence of equivalence statements, it is a violation of the language's semantics for two names to share memory. Codes 3 and 5 are C programs. In both cases, the compiler did not hoist all invariant memory operations from inner loops. Consider the following loop from code 3 for (y = 0; y < NY; y++) { i = 0; for (u = 0; u < NU; u++) { for (k = 0; k < NK[u]; k++) { dW[y][u][k] += delta[y] * I1[i++]; } } } Since dW[y][u] can point to the same memory space as delta for one or more values of y and u, assignment to dW[y][u][k] may change the value of delta[y]. In reality, dW and delta do not overlap in memory, so I rewrote the loop as for (y = 0; y < NY; y++) { i = 0; Dy = delta[y]; for (u = 0; u < NU; u++) { for (k = 0; k < NK[u]; k++) { dW[y][u][k] += Dy * I1[i++]; } } } Failure to hoist invariant memory operations may be due to complex address calculations. If the compiler can not determine that the address calculation is invariant, then it can hoist neither the calculation nor the associated memory operations. As noted above, code 5 uses a macro to address four-dimensional arrays #define MAT4D(a,q,i,j,k) (double *)((a)->data + (q)*(a)->strides[0] + (i)*(a)->strides[3] + (j)*(a)->strides[2] + (k)*(a)->strides[1]) The macro is too complex for the compiler to understand and so, it does not identify any subexpressions as loop invariant. The simplest way to eliminate the address calculation from the innermost loop (over i) is to define a0 = MAT4D(a,q,0,j,k) before the loop and then replace all instances of *MAT4D(a,q,i,j,k) in the loop with a0[i] A similar problem appears in code 6, a Fortran program. The key loop in this program is do n1 = 1, nh nx1 = (n1 - 1) / nz + 1 nz1 = n1 - nz * (nx1 - 1) do n2 = 1, nh nx2 = (n2 - 1) / nz + 1 nz2 = n2 - nz * (nx2 - 1) ndx = nx2 - nx1 ndy = nz2 - nz1 gxx = grn(1,ndx,ndy) gyy = grn(2,ndx,ndy) gxy = grn(3,ndx,ndy) balance(n1,1) = balance(n1,1) + (force(n2,1) * gxx + force(n2,2) * gxy) * h1 balance(n1,2) = balance(n1,2) + (force(n2,1) * gxy + force(n2,2) * gyy)*h1 end do end do The programmer has written this loop well—there are no loop invariant operations with respect to n1 and n2. However, the loop resides within an iterative loop over time and the index calculations are independent with respect to time. Trading space for time, I precomputed the index values prior to the entering the time loop and stored the values in two arrays. I then replaced the index calculations with reads of the arrays. Data operations Ways to reduce data operations can appear in many forms. Implementing a more efficient algorithm produces the biggest gains. The closest I came to an algorithm change was in code 4. This code computes the inner product of K-vectors A(i) and B(j), 0 = i < N, 0 = j < M, for most values of i and j. Since the program computes most of the NM possible inner products, it is more efficient to compute all the inner products in one triply-nested loop rather than one at a time when needed. The savings accrue from reading A(i) once for all B(j) vectors and from loop unrolling. for (i = 0; i < N; i+=8) { for (j = 0; j < M; j++) { sum0 = 0.0; sum1 = 0.0; sum2 = 0.0; sum3 = 0.0; sum4 = 0.0; sum5 = 0.0; sum6 = 0.0; sum7 = 0.0; for (k = 0; k < K; k++) { sum0 += A[i+0][k] * B[j][k]; sum1 += A[i+1][k] * B[j][k]; sum2 += A[i+2][k] * B[j][k]; sum3 += A[i+3][k] * B[j][k]; sum4 += A[i+4][k] * B[j][k]; sum5 += A[i+5][k] * B[j][k]; sum6 += A[i+6][k] * B[j][k]; sum7 += A[i+7][k] * B[j][k]; } C[i+0][j] = sum0; C[i+1][j] = sum1; C[i+2][j] = sum2; C[i+3][j] = sum3; C[i+4][j] = sum4; C[i+5][j] = sum5; C[i+6][j] = sum6; C[i+7][j] = sum7; }} This change requires knowledge of a typical run; i.e., that most inner products are computed. The reasons for the change, however, derive from basic optimization concepts. It is the type of change easily made at development time by a knowledgeable programmer. In code 5, we have the data version of the index optimization in code 6. Here a very expensive computation is a function of the loop indices and so cannot be hoisted out of the loop; however, the computation is invariant with respect to an outer iterative loop over time. We can compute its value for each iteration of the computation loop prior to entering the time loop and save the values in an array. The increase in memory required to store the values is small in comparison to the large savings in time. The main loop in Code 8 is doubly nested. The inner loop includes a series of guarded computations; some are a function of the inner loop index but not the outer loop index while others are a function of the outer loop index but not the inner loop index for (j = 0; j < N; j++) { for (i = 0; i < M; i++) { r = i * hrmax; R = A[j]; temp = (PRM[3] == 0.0) ? 1.0 : pow(r, PRM[3]); high = temp * kcoeff * B[j] * PRM[2] * PRM[4]; low = high * PRM[6] * PRM[6] / (1.0 + pow(PRM[4] * PRM[6], 2.0)); kap = (R > PRM[6]) ? high * R * R / (1.0 + pow(PRM[4]*r, 2.0) : low * pow(R/PRM[6], PRM[5]); < rest of loop omitted > }} Note that the value of temp is invariant to j. Thus, we can hoist the computation for temp out of the loop and save its values in an array. for (i = 0; i < M; i++) { r = i * hrmax; TEMP[i] = pow(r, PRM[3]); } [N.B. – the case for PRM[3] = 0 is omitted and will be reintroduced later.] We now hoist out of the inner loop the computations invariant to i. Since the conditional guarding the value of kap is invariant to i, it behooves us to hoist the computation out of the inner loop, thereby executing the guard once rather than M times. The final version of the code is for (j = 0; j < N; j++) { R = rig[j] / 1000.; tmp1 = kcoeff * par[2] * beta[j] * par[4]; tmp2 = 1.0 + (par[4] * par[4] * par[6] * par[6]); tmp3 = 1.0 + (par[4] * par[4] * R * R); tmp4 = par[6] * par[6] / tmp2; tmp5 = R * R / tmp3; tmp6 = pow(R / par[6], par[5]); if ((par[3] == 0.0) && (R > par[6])) { for (i = 1; i <= imax1; i++) KAP[i] = tmp1 * tmp5; } else if ((par[3] == 0.0) && (R <= par[6])) { for (i = 1; i <= imax1; i++) KAP[i] = tmp1 * tmp4 * tmp6; } else if ((par[3] != 0.0) && (R > par[6])) { for (i = 1; i <= imax1; i++) KAP[i] = tmp1 * TEMP[i] * tmp5; } else if ((par[3] != 0.0) && (R <= par[6])) { for (i = 1; i <= imax1; i++) KAP[i] = tmp1 * TEMP[i] * tmp4 * tmp6; } for (i = 0; i < M; i++) { kap = KAP[i]; r = i * hrmax; < rest of loop omitted > } } Maybe not the prettiest piece of code, but certainly much more efficient than the original loop, Copy operations Several programs unnecessarily copy data from one data structure to another. This problem occurs in both Fortran and C programs, although it manifests itself differently in the two languages. Code 1 declares two arrays—one for old values and one for new values. At the end of each iteration, the array of new values is copied to the array of old values to reset the data structures for the next iteration. This problem occurs in Fortran programs not included in this study and in both Fortran 77 and Fortran 90 code. Introducing pointers to the arrays and swapping pointer values is an obvious way to eliminate the copying; but pointers is not a feature that many Fortran programmers know well or are comfortable using. An easy solution not involving pointers is to extend the dimension of the value array by 1 and use the last dimension to differentiate between arrays at different times. For example, if the data space is N x N, declare the array (N, N, 2). Then store the problem’s initial values in (_, _, 2) and define the scalar names new = 2 and old = 1. At the start of each iteration, swap old and new to reset the arrays. The old–new copy problem did not appear in any C program. In programs that had new and old values, the code swapped pointers to reset data structures. Where unnecessary coping did occur is in structure assignment and parameter passing. Structures in C are handled much like scalars. Assignment causes the data space of the right-hand name to be copied to the data space of the left-hand name. Similarly, when a structure is passed to a function, the data space of the actual parameter is copied to the data space of the formal parameter. If the structure is large and the assignment or function call is in an inner loop, then copying costs can grow quite large. While none of the ten programs considered here manifested this problem, it did occur in programs not included in the study. A simple fix is always to refer to structures via pointers. Optimizing loop structures Since scientific programs spend almost all their time in loops, efficient loops are the key to good performance. Conditionals, function calls, little instruction level parallelism, and large numbers of temporary values make it difficult for the compiler to generate tightly packed, highly efficient code. Conditionals and function calls introduce jumps that disrupt code flow. Users should eliminate or isolate conditionls to their own loops as much as possible. Often logical expressions can be substituted for if-then-else statements. For example, code 2 includes the following snippet MaxDelta = 0.0 do J = 1, N do I = 1, M < code omitted > Delta = abs(OldValue ? NewValue) if (Delta > MaxDelta) MaxDelta = Delta enddo enddo if (MaxDelta .gt. 0.001) goto 200 Since the only use of MaxDelta is to control the jump to 200 and all that matters is whether or not it is greater than 0.001, I made MaxDelta a boolean and rewrote the snippet as MaxDelta = .false. do J = 1, N do I = 1, M < code omitted > Delta = abs(OldValue ? NewValue) MaxDelta = MaxDelta .or. (Delta .gt. 0.001) enddo enddo if (MaxDelta) goto 200 thereby, eliminating the conditional expression from the inner loop. A microprocessor can execute many instructions per instruction cycle. Typically, it can execute one or more memory, floating point, integer, and jump operations. To be executed simultaneously, the operations must be independent. Thick loops tend to have more instruction level parallelism than thin loops. Moreover, they reduce memory traffice by maximizing data reuse. Loop unrolling and loop fusion are two techniques to increase the size of loop bodies. Several of the codes studied benefitted from loop unrolling, but none benefitted from loop fusion. This observation is not too surpising since it is the general tendency of programmers to write thick loops. As loops become thicker, the number of temporary values grows, increasing register pressure. If registers spill, then memory traffic increases and code flow is disrupted. A thick loop with many temporary values may execute slower than an equivalent series of thin loops. The biggest gain will be achieved if the thick loop can be split into a series of independent loops eliminating the need to write and read temporary arrays. I found such an occasion in code 10 where I split the loop do i = 1, n do j = 1, m A24(j,i)= S24(j,i) * T24(j,i) + S25(j,i) * U25(j,i) B24(j,i)= S24(j,i) * T25(j,i) + S25(j,i) * U24(j,i) A25(j,i)= S24(j,i) * C24(j,i) + S25(j,i) * V24(j,i) B25(j,i)= S24(j,i) * U25(j,i) + S25(j,i) * V25(j,i) C24(j,i)= S26(j,i) * T26(j,i) + S27(j,i) * U26(j,i) D24(j,i)= S26(j,i) * T27(j,i) + S27(j,i) * V26(j,i) C25(j,i)= S27(j,i) * S28(j,i) + S26(j,i) * U28(j,i) D25(j,i)= S27(j,i) * T28(j,i) + S26(j,i) * V28(j,i) end do end do into two disjoint loops do i = 1, n do j = 1, m A24(j,i)= S24(j,i) * T24(j,i) + S25(j,i) * U25(j,i) B24(j,i)= S24(j,i) * T25(j,i) + S25(j,i) * U24(j,i) A25(j,i)= S24(j,i) * C24(j,i) + S25(j,i) * V24(j,i) B25(j,i)= S24(j,i) * U25(j,i) + S25(j,i) * V25(j,i) end do end do do i = 1, n do j = 1, m C24(j,i)= S26(j,i) * T26(j,i) + S27(j,i) * U26(j,i) D24(j,i)= S26(j,i) * T27(j,i) + S27(j,i) * V26(j,i) C25(j,i)= S27(j,i) * S28(j,i) + S26(j,i) * U28(j,i) D25(j,i)= S27(j,i) * T28(j,i) + S26(j,i) * V28(j,i) end do end do Conclusions Over the course of the last year, I have had the opportunity to work with over two dozen academic scientific programmers at leading research universities. Their research interests span a broad range of scientific fields. Except for two programs that relied almost exclusively on library routines (matrix multiply and fast Fourier transform), I was able to improve significantly the single processor performance of all codes. Improvements range from 2x to 15.5x with a simple average of 4.75x. Changes to the source code were at a very high level. I did not use sophisticated techniques or programming tools to discover inefficiencies or effect the changes. Only one code was parallel despite the availability of parallel systems to all developers. Clearly, we have a problem—personal scientific research codes are highly inefficient and not running parallel. The developers are unaware of simple optimization techniques to make programs run faster. They lack education in the art of code optimization and parallel programming. I do not believe we can fix the problem by publishing additional books or training manuals. To date, the developers in questions have not studied the books or manual available, and are unlikely to do so in the future. Short courses are a possible solution, but I believe they are too concentrated to be much use. The general concepts can be taught in a three or four day course, but that is not enough time for students to practice what they learn and acquire the experience to apply and extend the concepts to their codes. Practice is the key to becoming proficient at optimization. I recommend that graduate students be required to take a semester length course in optimization and parallel programming. We would never give someone access to state-of-the-art scientific equipment costing hundreds of thousands of dollars without first requiring them to demonstrate that they know how to use the equipment. Yet the criterion for time on state-of-the-art supercomputers is at most an interesting project. Requestors are never asked to demonstrate that they know how to use the system, or can use the system effectively. A semester course would teach them the required skills. Government agencies that fund academic scientific research pay for most of the computer systems supporting scientific research as well as the development of most personal scientific codes. These agencies should require graduate schools to offer a course in optimization and parallel programming as a requirement for funding. About the Author John Feo received his Ph.D. in Computer Science from The University of Texas at Austin in 1986. After graduate school, Dr. Feo worked at Lawrence Livermore National Laboratory where he was the Group Leader of the Computer Research Group and principal investigator of the Sisal Language Project. In 1997, Dr. Feo joined Tera Computer Company where he was project manager for the MTA, and oversaw the programming and evaluation of the MTA at the San Diego Supercomputer Center. In 2000, Dr. Feo joined Sun Microsystems as an HPC application specialist. He works with university research groups to optimize and parallelize scientific codes. Dr. Feo has published over two dozen research articles in the areas of parallel parallel programming, parallel programming languages, and application performance.

    Read the article

< Previous Page | 207 208 209 210 211 212 213 214 215 216 217 218  | Next Page >