Message boards : Number crunching : 64-Bit Rosetta?
Previous · 1 · 2 · 3 · Next
Author | Message |
---|---|
Leonard Kevin Mcguire Jr. Send message Joined: 13 Jun 06 Posts: 29 Credit: 14,903 RAC: 0 |
It depends on what size scope is considered general. More importantly what criteria would need to be meet to consider something a general "case"? Many general cases exist, by my definition of general, that involve routines that can have a performance gain - and thus this gain no matter how small is still a gain unless we are talking about non-general routines which might be: int main(void) { return (char)1 + (char)1; } Evidently this would yeild no use from 64 BIT. We only need to store one value, but it could be run in a 64 BIT enviroment!, and not use 64 BIT instructions and have a gain as I have read somewhere... let me go find it. mov eax, 1 add eax, 1 ret Is that a general case? I do not know of many useful programs that do something like that. Would this be a correlation? int main(int a, int b, int c, int d, int e, int f, int g, int h, int i, int k) { return a + b + c + d + e + f + g + h + i + k; } add eax, ebx // a=a+b add eax, ecx // a=a+c add eax, edx // a=a+d add eax, r08 // a=a+e add eax, r09 // a=a+f add eax, r10 // a=a+g add eax, r11 // a=a+h add eax, r12 // a=a+i add eax, r13 // a=a+k ret
1. I'm saying that in general, 2. there is no direct correlation between 2A. the bitness of an application or of a CPU and the performance seen. 2B. the bitness of an application and of a CPU and the performance seen. So for 2A we mean: A application using totaly 32bit instructions VS one using totaly 64bit instructions. (In general? Every application in the world that is considered a general case application? How are we to scientificly define this general?) Quite frankly you don't use storage space you do not need. It would be a waste to use a 64 bit operation on a 32 bit value unless wraparound was a unwanted effect. A application using only 32bit instructions VS one that can use 32bit instructions and 64bit instructions as such is the 64 bit AMD processors. So for 2B we mean: A application that uses only 32bit run on a 32bit processor VS a 32bit application run on a 64 bit processor. The performance should be no less in "general". =) A application that uses 32bit and 64bit or just 64bit run on a 32 bit processor VS a 64 bit processor. It will not work. =) |
dgnuff Send message Joined: 1 Nov 05 Posts: 350 Credit: 24,773,605 RAC: 0 |
Are you sure? If it's not the same problem, why, pray tell, was NT 4 on the DEC Alpha such a miserable failure? Why was Win 2K 64 bit on IA64 (Itanium) an even worse failure? And no it's not about pointer size. I'm not sure about the Alpha, but I know for a fact that the IA64 offered a "half pointer" (i.e. 32 bit) mode to solve the 64 bit pointer overhead problem. It's because a 64 bit processor does not automatically equate to extra speed, just as 32 bits didn't automaticaly equate to more speed over 16 bits, 15 years ago. I benchmarked programs when porting to IA 64. Not just "throw a 32 bit program at the IA 64 compiler and recompile" but actually rearchitect to make use of the 64 bit nature. Yes, some programs did run faster. Some ran a hell of a lot faster. But a good many programs did not, and some ran slower. This is exactly what BennyRop is trying to tell you. There is no hard and fast rule, and there are some programs that simply cannot be made to run faster by throwing more processor bits at them. Please read the second post here. That's from Keith Davis, author of THINK, the software behind the Find-A-Drug cancer project. The point he's making is that the algorithms in Think simply could not be improved by allowing the compiler to use SSE. And don't for an instant make the mistake of underestimating his ability to optimze. By working with Intel on that code, he got about a 40 to 1 speedup after Think and UD parted company. That doesn't mean that Rosetta can't benefit from SSE (or 64 bits for that matter). But it is quite a wakeup call for the fact that sometimes those technologies just can't do any good. |
Leonard Kevin Mcguire Jr. Send message Joined: 13 Jun 06 Posts: 29 Credit: 14,903 RAC: 0 |
Oh. I am sorry, I was completely wrong. You are right, dgnuff. Silly me! I am so glad we have smart people like you around to explain to idiots like me that 64 bits does not equate to more performance, it took me forever it understand what everyone is talking about, wow - I have been lost before but never this lost! Thank you lord! I have been saved from a hellish future! The world has been saved! |
BennyRop Send message Joined: 17 Dec 05 Posts: 555 Credit: 140,800 RAC: 0 |
Leonard spoketh: Oh. I am sorry, I was completely wrong. You are right, dgnuff. Silly me! I am so glad we have smart people like you around to explain to idiots like me that 64 bits does not equate to more performance, it took me forever it understand what everyone is talking about, wow - I have been lost before but never this lost! Thank you lord! I have been saved from a hellish future! The world has been saved! It's tempting to agree with your self assessment, Leonard. Especially after you keep changing your diagnosis of the problem with DF's 64 bit compilation. When looking at advantages of 64 bit apps - it's important to keep in mind the disadvantages of 64 bit apps and work around them. If you take offense at my giving detailed reports on what I've run across on the subject, then keep in mind that when the Intel fanboys get together and state how much better Intel parts are than AMD cpus because they saw a video of an AMD cpu blowing up on Tom's Hardware - I'll likewise point out my experience with customer's AMD systems that only stayed on for a few seconds and kept shutting off. (HSF wasn't mounted correctly and wasn't making proper contact with the cpu - i.e. newer AMD cpus and motherboards don't have that problem.) I've pointed out the benefits of the Core Duo cpus over the lesser Intel cpus and AMD parts; so I'm loyal to a balanced view - not just 100% positive or negative reporting while trying to hide/ignore the other side. Xeno's mention of "the huge performance benefit in using 64-bit processing?" was not born out by a 64 bit app that ran at 50%-75% of the speed of the 32 bit version over at DF. Having to properly optimize a 64 bit client to get it to run at roughly the same speed as the 32 bit version would not qualify as "the huge performance benefit in using 64-bit processing." |
skutnar Send message Joined: 31 Oct 05 Posts: 8 Credit: 133,153 RAC: 0 |
LOL, Leonard... I'm not sure what you're agenda is in trying to tear apart every word of what I wrote and give some contrived examples. You haven't demonstrated to me, at least, that my earlier statements are incorrect. |
skutnar Send message Joined: 31 Oct 05 Posts: 8 Credit: 133,153 RAC: 0 |
Nice discussion! ;-) I think it's been mentioned earlier in this discussion and in other threads that the Rosetta developers had been looking at this issue. |
Mats Petersson Send message Joined: 29 Sep 05 Posts: 225 Credit: 951,788 RAC: 0 |
No, DUH! Use int and get a 64 bit integer, and increase the cache needed. You should work for a news channel! =) That is incorrect for both the GCC and Microsoft x86-64-compilers, and most likely all other compilers for this architecture - I obviously can't speak for compilers for different architectures, but I think this generally holds true. The type "int" in both of those compilers is 32-bit. "long" would be reguired to get a 64-bit integer (which of course, in a 32-bit compiler will still be 32-bit - and there's no guarantee that some programmer has used "long int" when they actually just wanted a 32-bit entity, of course). I may not have expressed it very clearly, but I _HAVE_ quite a bit of experience doing comparative benchmarking and improving performance on x86(-64) architecture, and I _DO_ know a fair bit about tricks you can play with passing multiple arguments in a single register, etc, etc. However, those tricks assume either a compiler that can implement them - which isn't the case for either of the two I mention above - or a programmer that makes the effort to implement this by hand (using macros or similar methods, probably). Finally, a store to memory is a single cycle when the store-target is in L1 cache, which the stack will almost certainly be for any call-intensive code. Performing two single cycle but dependant operations to merge some data into a single register doesn't make sense under those conditions. Of course, on x86_64, there will be more registers available for passing values in registers from one function to another, which helps. A plain (i.e. just compile it 64-bit instead of 32-bit) 64-bit compile of SOME applications will give 30% performance boost. Other applications may well loose the same amount, because they are cache-dependant, and bigger pointers are using more cache-space. Yes, you could convince the compiler to use 32-bit pointers, but you'd have to also use a special C-library designed for this purpose [of which there are none available today AFAIK], and make sure that any calls to the OS itself is "filtered" suitably for your app, etc, etc. Which makes this variation fairly unpractical - it's unlikely that such a cache-bound app would gain noticably from running with more/bigger registers anyays, so those apps are better off running 32-bit binaries - unless you actually want bigger memory space, in which case 32-bit pointers are a moot point. Some applications neither gain nor loose, because the performance bottleneck is neither calling-convention, register usage or cache-usage, but simply CPU-clock-cycles - everything is cached, the code is running flat out. Another category is where memory is the limit of performance - in which case there are some clever tricks you can play with buffered data-handling, assuming there's some linear pattern which the data can be fetched in, rather than a telephone switch system where each access is pretty much random (from the switch's standpoint, every call goes to/from different telephone numbers, so each access is completely uncached [in fact, it's sometimes better to not ever cache this data, since that will just throw out other data from the cache, but that does depend on the amount of processing needed for each call] and not in any way predictable). Again, these applications will perform almost identical in 64-bit as in 32-bit, since it's some other factor that determines performance. My point is that you can not, without understanding quite a bit about the application, say whether it will run faster, slower or at the same speed when moving from 32-bit to 64-bit. I also haven't looked at the math in Rosetta - it may all be "linear", which means that no great gains can be had from optimizing it with SSE-instructions. SSE instructions are very useful for doing multiple calculations in parallel, but for something like: for (i = 1; i < large_number; i++) { x[i] = x[i-1] + y[i]; } where the result of on calculation is dependant on the previous one, the SSE doesn't buy you anything, because you can't perform this in parallel. SSE instructions aren't faster, per se, than FPU instructons (in AMD64, at least - may be different with Intel processors, I haven't done performance tuning with one of those since before AMD had SSE instructions, so I can't say). -- Mats |
tralala Send message Joined: 8 Apr 06 Posts: 376 Credit: 581,806 RAC: 0 |
I couldn't find any mention of this in all the threads. In fact to my knowledge they do try to optimize Rosetta and use compiler optimization settings to be sure, but never looked specifically into the possibilities of SSE/3DNow and 64 BIT. What I would like to do to let some knowledgeable people fathom the possibilities of these specific optimizations. If I understand all those posts correctly SSE and 64Bit _might_ offer significant optimization potential but not necessarily for all applications. It's fruitless to debate all the optimization potential for Rosetta without really looking on the code. |
Leonard Kevin Mcguire Jr. Send message Joined: 13 Jun 06 Posts: 29 Credit: 14,903 RAC: 0 |
You are a retard. I have written a operating system kernel from scratch! I should know! Yes!
I am so tired of this crap.
http://www.unix.org/whitepapers/64bit.html All I have to say, is for all the "fake" stupid idiots that rant and rave about crap they don't know for sure can kiss my white butt. Optimize the Rosetta@Home application your self, since it seems you people don't want to attempt to talk about something constructive apon it helping - instead every single post (almost) was a negative buncha crap.
You wish you knew something. I can not prove it, but I know it. I am so mad, I do not care. So if you post any other CRAP above this, just know I am going to read it and laugh at you. |
Mats Petersson Send message Joined: 29 Sep 05 Posts: 225 Credit: 951,788 RAC: 0 |
I guess you can do with a laugh, so here we go... You are a retard. I have written a operating system kernel from scratch! I should know! Yes! As if that matters, so have I... It's not hard, if you have read a book or two on the subject... roughly: after interrupt, look at task-list, run the highest priority task. If nothing runnable, wait for another interrupt. Of course, it gets a bit more complicated when you start involving paging, floating-point-lazy-saving, and other advanced features. But it's still just a matter of programming, just like anything. It's not that hard - as obvious by the fact that a retard like me can manage it...
And this proves exactly what? According to the table, all the 64-bit designs have 64-bit pointers, which means that a task that uses pointers heavily will be running slower on a 64-bit machine than on a 32-bit machine.
As far as I'm concerned, what I stated is true. I've also had a look at the profile of rosetta, using oprofile. It's quite clear that it spends most of it's time doing floating point operations. It's not using a huge amount of memory whilst doing these calculations, as it's not getting cache-misses very often (roughly one per every 2-3K instructions executed, which is definitely (a lot) better than some other code I've looked at). Some instruction counts 15000 fmul, 12500 fadd, 7000 fsub, 1200 fdiv, 37000 fld, 36000 fst instructions that are in the code. call instruction: 180000 call to 0x888f250: 8325 call to 0x8898bec: 7399 call to 0x888d640: 4577 call to 0x8890b26: 4596 call to 0x8054454: 3932 call to 0x883f8b0: 3494 That's just the functions that are called more than 3000 times in the code. I haven't looked at all these functions (or any of the others) to understand what of this could potentially be optimized, or by what method. I've seen some short functions that are called a few hundred times that could perhaps be inlined - but it may not give ANY benefit whatsoever, since they may only be called on error-paths or in code that isn't repeated very much. It's probably fair to say that this code follows the regular 90:10 rule, 90% of the work is done in 10% of the code, and I'm not at a position where I can say exactly which part of this huge piece of code is actually executing a lot. I also looked at some of the floating point code, and at least parts look like it could be optimized to some extent with SSE instructions - but again, I have no idea whether the code I looked at is what executes a lot or not - since that would require a bit more analyzis of the code, and I'm not usually at work at ten to one in the morning to do research. Now it's your turn to come up with something USEFUL, I should think. -- Mats |
Leonard Kevin Mcguire Jr. Send message Joined: 13 Jun 06 Posts: 29 Credit: 14,903 RAC: 0 |
Alright. Here is a function, unknown to me exactly what it is. Samples Address Code Bytes Instruction Symbol CPU0 Event:0x41 0x494a50 0x 56 push esi 0x494a51 0x 57 push edi 0x494a52 0x 8B 7C 24 0C mov edi,[esp+0ch] 0x494a56 0x 8B F1 mov esi,ecx 0x494a58 0x 3B F7 cmp esi,edi 0x494a5a 0x 74 2D jz $+2fh (0x494a89) 0x494a5c 0x 57 push edi 0x494a5d 0x E8 7E F4 FF FF call $-00000b7dh (0x493ee0) 0x494a62 0x 84 C0 test al,al 0x494a64 0x 75 08 jnz $+0ah (0x494a6e) 0x494a66 0x 57 push edi 0x494a67 0x 8B CE mov ecx,esi 0x494a69 0x E8 92 FE FF FF call $-00000169h (0x494900) 0x494a6e 0x 33 C0 xor eax,eax 0x494a70 0x 39 46 0C cmp [esi+0ch],eax 0x494a73 0x 76 14 jbe $+16h (0x494a89) [b] 23 0x494a75 0x 8B 4F 08 mov ecx,[edi+08h] 23 34 0x494a78 0x D9 04 81 fld dword ptr [ecx+eax*4] 34 988 0x494a7b 0x 8B 56 08 mov edx,[esi+08h] 988 0x494a7e 0x D9 1C 82 fstp dword ptr [edx+eax*4] 995 0x494a81 0x 83 C0 01 add eax,01h 995 1 0x494a84 0x 3B 46 0C cmp eax,[esi+0ch] 1 0x494a87 0x 72 EC jb $-12h (0x494a75) [/b] 0x494a89 0x 5F pop edi 0x494a8a 0x 8B C6 mov eax,esi 0x494a8c 0x 5E pop esi 6 0x494a8d 0x C2 04 00 ret 0004h 6 This is apparently where alot of cache misses are occuring, just a thought, if it is copying a large array, as in the case when I broke the thread. The cache misses might just be too bad for such a large array, but on a AMD64 capable processor would the below even though not erasing the cache misses be benificial? cmp eax, [esi+0ch] 0x494a84 *((unsigned long*)(esi + 0xC)) = 0x11D In this instance it was moving (285 * 4) bytes with 285 loops. EAX starts at 0x0, so its definitly looping. Could a 64BIT move be faster than using the floating point unit to perform a data move? Apparently the floating point unit can move it faster than a 32 bit move, as the code is using the x87? (I do not know) [The x87 might be slower, mabye the compiler just did not optimize it correctly?) My WIN32 executables .text section's virtual address is 0x401000. That could help pinpoint where the function is since I'm pretty sure a linux build's CRT might offset it differently? [edit:] I actually looked at the darn code some more and figured it couldnt be optimized at all since it repeatadly loads ecx and edx with the same value. You know I just noticed from your results that it does alot of FP store and load operations, the potential of MMX to reduce transfers from main memory to FP registers? I do think all AMD(I do not know alot about INTEL) 64 processors support the MMX instructions.. I am just guessing here. And in reply to the SSE being slower than the x87 instructions. I have read that SSE is actually slower, and the only performance gain is by using it to perform multiple operations. |
Mats Petersson Send message Joined: 29 Sep 05 Posts: 225 Credit: 951,788 RAC: 0 |
Now, this is USEFUL discussion... Alright. Here is a function, unknown to me exactly what it is. This is typical for a loop like: for(i = 0; i < something; i++) a[i] = b[i]; where what you really would want to do is memcpy(a, b, sizeof(a[0]) * something); It is also, as you say, completely unnecesseary to use floating point load/store operations. Although, I'm not sure it makes a whole lot of difference. The reason you get cache-misses in this piece of code is probably that every time a and b are copied, they are (let's say) segments/chunks from a different locations, so the current location isn't in cache when this happens - or because it's not running some other code inbetween that fills the cache with something else, then takes another copy of this data. Is this also the place where you see a lot of hits if you run use profiling in timer-mode? Unfortunately, cache-misses aren't going to be solved by using 64-bit or 128-bit (SSE) loads/stores. However, there's only so many load/store "slots" in the processor, which means that when the processor is waiting for X outstanding loads or stores, it's stopped from executing something else. Loads/stores can be performed speculatively and out of roder, so there's no reason for the processor to stall until these slots are filled up. So using bigger units (64- or 128-bit) can be helpfull to get more data copied before the slots are stacked up. As the loop is quite short, it's unlikely that it will benefit from prefetch instructions - that usually works on bigger copies, but small ones don't really benefit much. I did a little experiment where I copy 256 floats at a time, over a 16MB array, using different methods: 1. float 25000 cycles (100.0%) 2. int32 24600 cycles (98.0%) 3. int64 21600 cycles (86.0%) 4. sse128 21500 cycles (85.6%) The numbare slightly rounded, but as you can see, it's the size of the copy-item that matters, more than the actual register type that is used for the copy-mechanism. Each copy method is run 15 times, with the 13 "middle" values averaged to get a good value. And the machine is running all sorts of things in the background, as I can't just shut things down for this benchmark - but it's the same for all of the tests, and I can run the test several times, and it only varies a hundred or so cycles up or down for each test. By the way, using gcc for this, and I had to actually write the loop by hand for the float-copy method, as the compiler would automatically convert the a[i] = b[i]; copy operation to a integer transaction. There may be a way to avoid this, but I didn't look for it. However, I also did a version that uses the C-library memcpy() function: 5. memcpy 3600 cycles (14.4%) Now, that's what I call a saving... 85+% faster than the original code... The C-library memcpy function is highly optimized and uses a range of different methods to copy data, depending on the size and alignment of the source and destination. So, at least for Linux, it would definitely make sense to copy blocks of data, not with a loop, but with a memcpy() call... I doubt it's slower in the Windows case either... Edit: I'm wondering tho', that this may not give ANY speed change to the application, because although this particular section is the one getting Cache-misses, Cache-misses aren't a large problem in Rosetta, since there's only one cache-miss for every 2-3K instructions or so. -- Mats |
Leonard Kevin Mcguire Jr. Send message Joined: 13 Jun 06 Posts: 29 Credit: 14,903 RAC: 0 |
You were right about the data move routines, they stayed right about the same for each one independant of the register size used. I must meditate on this. |
Leonard Kevin Mcguire Jr. Send message Joined: 13 Jun 06 Posts: 29 Credit: 14,903 RAC: 0 |
Hmmm.. So it seems you were right and I know why, and I am not mad. It could benifit more from SSE rather than 64 BIT instructions primarly because most operations work in cache when moving around data, and the rest is FP operations - and if not so its rarely called functions that have cache misses that move alot of data around so no big deal. I came to this conclusion after trying to figure out a way to optimize the function at the file address 0x204050 in the windows PE32 build. I used a timer, and it found that this function gets called alot. It seems like it takes about 3 arguments - looks just like a vector subtraction at the start, anyway, after looking the function over and over. I could find no where to optimize it favorable >:) with 64bit instructions. I am not saying there is absolutely no performance to be gained, but its prolly not going to be in the core of the application as the 90:10 rule you stated in a earlier post. However, I did notice a few operations of load/store that where kind of redundant looking unless the rounding effect was intentional (80bit[fp reg] -> 32bit[mem]... "fstp fld"). I will look at it some more in a direction towards SSE =). At least this sorta stops the 64bit fanboy arguments! |
Leonard Kevin Mcguire Jr. Send message Joined: 13 Jun 06 Posts: 29 Credit: 14,903 RAC: 0 |
I found a interesting function that could use SSE: 00604050 sub esp,0Ch 00604053 push esi 00604054 mov esi,dword ptr [esp+1Ch] 00604058 fld dword ptr [esi] 0060405A push edi 0060405B mov edi,dword ptr [esp+4Ch] 0060405F fsub dword ptr [edi] 00604061 mov eax,dword ptr [esp+88h] 00604068 fstp dword ptr [esp+0Ch] 0060406C fld dword ptr [esi+4] 0060406F fsub dword ptr [edi+4] 00604072 fstp dword ptr [esp+8] 00604076 fld dword ptr [esi+8] 00604079 fsub dword ptr [edi+8] 0060407C fstp dword ptr [esp+10h] 00604080 fld dword ptr [esp+8] 00604084 fld dword ptr [esp+0Ch] 00604088 fld dword ptr [esp+10h] .... I replaced the x87 instructions with SSE. 00604050 83 EC 0C sub esp,0Ch 00604053 56 push esi 00604054 57 push edi 00604055 8B 74 24 20 mov esi,dword ptr [esp+20h] 00604059 8B 7C 24 4C mov edi,dword ptr [esp+4Ch] 0060405D 0F 10 06 movups xmm0,xmmword ptr [esi] 00604060 0F 10 0F movups xmm1,xmmword ptr [edi] 00604063 0F 5C C1 subps xmm0,xmm1 00604066 0F C6 C1 4B shufps xmm0,xmm1,4Bh 0060406A 8B 44 24 10 mov eax,dword ptr [esp+10h] 0060406E 0F 11 4C 24 04 movups xmmword ptr [esp+4],xmm1 00604073 89 44 24 10 mov dword ptr [esp+10h],eax 00604077 8B 84 24 88 00 00 00 mov eax,dword ptr [esp+88h] 0060407E 90 nop 0060407F 90 nop 00604080 D9 44 24 08 fld dword ptr [esp+8] 00604084 D9 44 24 0C fld dword ptr [esp+0Ch] 00604088 D9 44 24 10 fld dword ptr [esp+10h] ... Do you think SSE will give a significant performace gain with something like that? I had to use a shufps, because I thought/think it was swapping the first two FPs. r[1] = a[0] - b[0] r[0] = a[1] - b[1] r[2] = a[2] - b[2] The forth over-writes other stuff in the stack, so I preserve it using eax - mabye all the extra overhead just kills any gain? |
Mats Petersson Send message Joined: 29 Sep 05 Posts: 225 Credit: 951,788 RAC: 0 |
I don't know, there would probably be a little benefit from using SSE here, but it would be even better if you can continue with the value in SSE further down. The code at 604080 is loading what you've just calculated into xmm1 - which, by the way, at 60406E you're storing one dword too high up on the stack, you should store at [esp+8]. Having source to be able to modify would help a whole lot here... Question: Is this one of the top-hit functions? -- Mats |
Mats Petersson Send message Joined: 29 Sep 05 Posts: 225 Credit: 951,788 RAC: 0 |
A few more thoughts... It's pretty much meaningless to round by saving the value and then reading it back out again - it's most likely just the compiler being stupid. From what I can see, the code doesn't look hyper-optimized by any means. It's probably not "no optimization", but it's not "-Ox" either (That's "Enable almost all optimizations"). Of course, enabling more optimization sometimes makes the code break - either because the code is written badly, or because the compiler is buggy, or both. With a huge project (which Rosetta certainly is), it can be hard to find those nasty bugs that are caused by high levels of optimization - particularly since the compiled code is much less readable when you turn on more optimization, the compiler often shuffles instructions to places that are dozens or more instructions away from the original source-code-line that you wrote, and may well shuffle conditional code so that you can't really recognize where it came from.... But someone else said that the code is compiled with "the highest available optimization", which doesn't seem to be true. Of course, that's not to say that the code will necessarily run noticably faster with more optimization - when I tried higher optimization level on my memory-copy test, it ran slower (only a little bit, but slower)... :-( [The lowest level of optimization was quite a lot slower, tho'] -- Mats |
Mats Petersson Send message Joined: 29 Sep 05 Posts: 225 Credit: 951,788 RAC: 0 |
By the way, you should be able to make more space on the stack by another 4 bytes, and thus not overwrite anything ... -- Mats |
Leonard Kevin Mcguire Jr. Send message Joined: 13 Jun 06 Posts: 29 Credit: 14,903 RAC: 0 |
I was doing some reading, and come across: http://www.gamedev.net/community/forums/topic.asp?topic_id=363892 That was not much, but then I read: http://72.14.209.104/search?q=cache:Z7_1qzYnxqQJ:asci-training.lanl.gov/BProc/SSE.html+sse+%22single+scalar%22&hl=en&gl=us&ct=clnk&cd=2 Alot of people have always said, with-out quotes, SSE is only good for doing multiple calculations using one instruction like the name implies. However, SSE supports some Single Scalar instructions that only perform one operation per instruction sorta mimic-ing the x87. According to the last link using SSE with single percision scalars is faster and more efficent than the x87, but using it for double percision scalars is about equal to the x87. That sounds like good news, or is there more to this? You would have to read that last link to see what I read near the top of the page. Unfourtunatly I also read this: http://72.14.209.104/search?q=cache:w4T3-RFklbYJ:www.ddj.com/184406205+x87+instructions&hl=en&gl=us&ct=clnk&cd=10&client=firefox-a That describes that fact that the x87 defaulty provides 80bit percision. According to that - even though Rosetta@Home only uses single percision(32bit) floats, it is only referencing the fact of how these are written/read from/to the x87 unit. Potentialy alot of Rosetta's calculations have become dependant on the 80bit percision and may not function at the required accuracy by using SSE? However the article also states the workarounds as to use double percision with SSE to aleviate or fix the 80bit percision problem? I am not sure if 64bit floats would do enough justice? Neverless, apparently that would still be equal to the x87 performance on modern day processors. The AMD64 seems to recommend using SSE instead of x87 even with double percision(64bit) floats, but I am not pulling a fanboy episode - just throwing this out there as to what is going on? Let me retype that, "I *think* the article recommeneds using double percision SSE instructions over x87 on a AMD64". |
Leonard Kevin Mcguire Jr. Send message Joined: 13 Jun 06 Posts: 29 Credit: 14,903 RAC: 0 |
So essentially by using SSE I lose 80 bit precision for a choice of 32 bit precision or 64 bit precision of the calculations. Even though the SSE uses 128 bit registers. MMX I think offers 128 bit operations, but I do not know if these would have a performance boost from x87? I think SSE2 allows 128bit operations, although my processor does not support it. I end up doing the first part of the other function like so to get double percision. sub esp, 0Ch push esi push edi mov esi,dword ptr [esp+20h] mov edi,dword ptr [esp+4Ch] // todo:fix: unaligned move, data potentialy allocated unaligned. // load two double floats from esi and edi movups xmm0, xmmword ptr [esi] shufps xmm0, xmm0, 050h movups xmm1, xmmword ptr [edi] shufps xmm1, xmm1, 050h // load remaining double float from esi and edi movups xmm2, xmmword ptr [esi] shufps xmm2, xmm2, 0FAh; movups xmm3, xmmword ptr [edi] shufps xmm3, xmm3, 0FAh; // vector subtraction subpd xmm0, xmm1 subsd xmm2, xmm3 |
Message boards :
Number crunching :
64-Bit Rosetta?
©2024 University of Washington
https://www.bakerlab.org