3 ms·
I've never seen anyone store 10 byte IEEE-754 values in memory. People store doubles, and people get upset when compiler optimizations (like when to spill from
by wolf550e 10y ago
I've never seen anyone store 10 byte IEEE-754 values in memory.
People store doubles, and people get upset when compiler optimizations (like when to spill from registers to memory and whether to use one or two instructions for multiply-and-add) change not just the performance but also the result of computations.
- qb45 10y ago> I've never seen anyone store 10 byte IEEE-754 values in memory. But you can, if you are after precision as the OP apparently was. I'm not sure what this c-word is doing in your post, I thought we were talking assembly, but as far as c-things go, at least gcc and clang represent long double as 80b extended precision on x86. So, for example, compiling this beauty (which is too large for x87 stack): long double a[64], b[64], c[64], d[64]; // load a,b,c,d from somewhere long double x = ((((((((a[0]+a[1])+(a[2]+a[3]))+((a[4]+a[5])+(a[6]+a[7]))) +(((a[8]+a[9])+(a[10]+a[11]))+((a[12]+a[13])+(a[14]+a[15])))) +((((a[16]+a[17])+(a[18]+a[19]))+((a[20]+a[21])+(a[22]+a[23]))) +(((a[24]+a[25])+(a[26]+a[27]))+((a[28]+a[29])+(a[30]+a[31]))))) +(((((a[32]+a[33])+(a[34]+a[35]))+((a[36]+a[37])+(a[38]+a[39]))) +(((a[40]+a[41])+(a[42]+a[43]))+((a[44]+a[45])+(a[46]+a[47])))) +((((a[48]+a[49])+(a[50]+a[51]))+((a[52]+a[53])+(a[54]+a[55]))) +(((a[56]+a[57])+(a[58]+a[59]))+((a[60]+a[61])+(a[62]+a[63])))))) +((((((b[0]+b[1])+(b[2]+b[3]))+((b[4]+b[5])+(b[6]+b[7]))) +(((b[8]+b[9])+(b[10]+b[11]))+((b[12]+b[13])+(b[14]+b[15])))) +((((b[16]+b[17])+(b[18]+b[19]))+((b[20]+b[21])+(b[22]+b[23]))) +(((b[24]+b[25])+(b[26]+b[27]))+((b[28]+b[29])+(b[30]+b[31]))))) +(((((b[32]+b[33])+(b[34]+b[35]))+((b[36]+b[37])+(b[38]+b[39]))) +(((b[40]+b[41])+(b[42]+b[43]))+((b[44]+b[45])+(b[46]+b[47])))) +((((b[48]+b[49])+(b[50]+b[51]))+((b[52]+b[53])+(b[54]+b[55]))) +(((b[56]+b[57])+(b[58]+b[59]))+((b[60]+b[61])+(b[62]+b[63]))))))) +(((((((c[0]+c[1])+(c[2]+c[3]))+((c[4]+c[5])+(c[6]+c[7]))) +(((c[8]+c[9])+(c[10]+c[11]))+((c[12]+c[13])+(c[14]+c[15])))) +((((c[16]+c[17])+(c[18]+c[19]))+((c[20]+c[21])+(c[22]+c[23]))) +(((c[24]+c[25])+(c[26]+c[27]))+((c[28]+c[29])+(c[30]+c[31]))))) +(((((c[32]+c[33])+(c[34]+c[35]))+((c[36]+c[37])+(c[38]+c[39]))) +(((c[40]+c[41])+(c[42]+c[43]))+((c[44]+c[45])+(c[46]+c[47])))) +((((c[48]+c[49])+(c[50]+c[51]))+((c[52]+c[53])+(c[54]+c[55]))) +(((c[56]+c[57])+(c[58]+c[59]))+((c[60]+c[61])+(c[62]+c[63])))))) +((((((d[0]+d[1])+(d[2]+d[3]))+((d[4]+d[5])+(d[6]+d[7]))) +(((d[8]+d[9])+(d[10]+d[11]))+((d[12]+d[13])+(d[14]+d[15])))) +((((d[16]+d[17])+(d[18]+d[19]))+((d[20]+d[21])+(d[22]+d[23]))) +(((d[24]+d[25])+(d[26]+d[27]))+((d[28]+d[29])+(d[30]+d[31]))))) +(((((d[32]+d[33])+(d[34]+d[35]))+((d[36]+d[37])+(d[38]+d[39]))) +(((d[40]+d[41])+(d[42]+d[43]))+((d[44]+d[45])+(d[46]+d[47])))) +((((d[48]+d[49])+(d[50]+d[51]))+((d[52]+d[53])+(d[54]+d[55]))) +(((d[56]+d[57])+(d[58]+d[59]))+((d[60]+d[61])+(d[62]+d[63])))))))) ; produces only 80b spills (fstpt in GNU syntax): $ objdump -d fpmonster |grep fst 400457: db 7c 1c 10 fstpt 0x10(%rsp,%rbx,1) 400462: db bc 1c 10 04 00 00 fstpt 0x410(%rsp,%rbx,1) 400470: db bc 1c 10 08 00 00 fstpt 0x810(%rsp,%rbx,1) 40047e: db bc 1c 10 0c 00 00 fstpt 0xc10(%rsp,%rbx,1) 400b47: db 7c 24 10 fstpt 0x10(%rsp) 400d91: db 3c 24 fstpt (%rsp) Clearly, extended precision can be done right both in C and raw assembly. > People store doubles, and people get upset That's their fault :) and another story altogether. For reproducible low precision, indeed SSE is the way to go.