为何Avx.Multiply运算效率未远高于*运算符?
SSE/AVX指令性能测试异常解惑
我在研究SSE与AVX的工作原理及优势时编写了测试代码,结果意外发现System.Runtime.Intrinsics.X86.Avx.Multiply仅比传统*运算符快不足5%;更极端的是,在批量字节乘法的测试中,使用SSE指令的版本速度反而更慢,恳请解惑。
浮点乘法测试代码及结果
(long TicksSse2, long TicksAlu) TestFloat() { Vector256<float> x = Vector256.Create((float)255, (float)128, (float)64, (float)32, (float)16, (float)8, (float)4, (float)2); Vector256<float> y = Vector256.Create((float).5); Stopwatch timerSse = new Stopwatch(); Stopwatch timerAlu = new Stopwatch(); for (int cnt = 0; cnt < 100_000_000; cnt++) { timerSse.Start(); var xx = Avx.Multiply(x, y); timerSse.Stop(); timerAlu.Start(); float a = (float)255 * (float).5; float b = (float)128 * (float).5; float c = (float)64 * (float).5; float d = (float)32 * (float).5; float e = (float)16 * (float).5; float f = (float)8 * (float).5; float g = (float)4 * (float).5; float h = (float)2 * (float).5; timerAlu.Stop(); } return (timerSse.ElapsedMilliseconds, timerAlu.ElapsedMilliseconds); // 测试结果:timerSse = 1688ms; timerAlu = 1748ms. }
字节乘法测试代码及结果
Vector128<byte> MultiplyBytes(Vector128<byte> x, Vector128<byte> y) { Vector128<ushort> xAsUShort = x.AsUInt16(); Vector128<ushort> yAsUShort = y.AsUInt16(); Vector128<ushort> dstEven = Sse2.MultiplyLow(xAsUShort, yAsUShort); Vector128<ushort> dstOdd = Sse2.MultiplyLow(Sse2.ShiftRightLogical(xAsUShort, 8), Sse2.ShiftRightLogical(yAsUShort, 8)); return Sse2.Or(Sse2.ShiftLeftLogical(dstOdd, 8), Sse2.And(dstEven, helper)).AsByte(); } (long TicksSse2, long TicksAlu) TestBytes() { Vector128<byte> x = Vector128.Create((byte)1, (byte)2, (byte)3, (byte)4, (byte)5, (byte)6, (byte)7, (byte)8, (byte)9, (byte)10, (byte)11, (byte)12, (byte)13, (byte)14, (byte)15, (byte)16); Vector128<byte> y = Vector128.Create((byte)2); Stopwatch timerSse = new Stopwatch(); Stopwatch timerAlu = new Stopwatch(); for (int cnt = 0; cnt < 100_000_000; cnt++) { timerSse.Start(); var xx = MultiplyBytes(x, y); timerSse.Stop(); timerAlu.Start(); byte a = (byte)1 * (byte)2; byte b = (byte)2 * (byte)2; byte c = (byte)3 * (byte)2; byte d = (byte)4 * (byte)2; byte e = (byte)5 * (byte)2; byte f = (byte)6 * (byte)2; byte g = (byte)7 * (byte)2; byte h = (byte)8 * (byte)2; byte i = (byte)9 * (byte)2; byte j = (byte)10 * (byte)2; byte k = (byte)11 * (byte)2; byte l = (byte)12 * (byte)2; byte m = (byte)13 * (byte)2; byte n = (byte)14 * (byte)2; byte o = (byte)15 * (byte)2; byte p = (byte)16 * (byte)2; timerAlu.Stop(); } return (timerSse.ElapsedMilliseconds, timerAlu.ElapsedMilliseconds); // 测试结果:timerSse = 3439ms; timerAlu = 1800ms }
内容的提问来源于stack exchange,提问作者André Reichelt
相关产品推荐
相关产品推荐

