Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在.NET framework 4.6中使用C#中的SIMD操作速度较慢_C#_.net_Ryujit - Fatal编程技术网

在.NET framework 4.6中使用C#中的SIMD操作速度较慢

在.NET framework 4.6中使用C#中的SIMD操作速度较慢,c#,.net,ryujit,C#,.net,Ryujit,我目前正在尝试使用C#计算一个巨大数组中所有值的总和,并使用SIMD比较性能,SIMD版本的速度要慢得多。请参阅下面的代码片段,如果我遗漏了什么,请告诉我。“VAL”是一个巨大的数组,它从图像文件中读取并省略该部分以保持精简 var watch1 = new Stopwatch(); watch1.Start(); var total = vals.Aggregate(0, (a, i) => a + i); watch1.Stop(); Console.WriteLine(string.

我目前正在尝试使用C#计算一个巨大数组中所有值的总和,并使用SIMD比较性能,SIMD版本的速度要慢得多。请参阅下面的代码片段,如果我遗漏了什么,请告诉我。“VAL”是一个巨大的数组,它从图像文件中读取并省略该部分以保持精简

var watch1 = new Stopwatch();
watch1.Start();
var total = vals.Aggregate(0, (a, i) => a + i);
watch1.Stop();
Console.WriteLine(string.Format("Total is: {0}", total));
Console.WriteLine(string.Format("Time taken: {0}", watch1.ElapsedMilliseconds));

var watch2 = new Stopwatch();
watch2.Start();
var sTotal = GetSIMDVectors(vals).Aggregate((a, i) => a + i);
int sum = 0;
for (int i = 0; i < Vector<int>.Count; i++)
    sum += sTotal[i];
watch2.Stop();
Console.WriteLine(string.Format("Another Total is: {0}", sum));
Console.WriteLine(string.Format("Time taken: {0}", watch2.ElapsedMilliseconds));
var watch1=新秒表();
watch1.Start();
var total=价值合计(0,(a,i)=>a+i);
watch1.Stop();
WriteLine(string.Format(“Total是:{0}”,Total));
WriteLine(string.Format(“花费的时间:{0}”,watch1.elapsedmillesons));
var watch2=新秒表();
watch2.Start();
var sTotal=GetSimdVector(VAL).聚合((a,i)=>a+i);
整数和=0;
对于(int i=0;i
以及GetSIMDVectors方法

private static IEnumerable<Vector<int>> GetSIMDVectors(short[] source)
{
    int vecCount = Vector<int>.Count;
    int i = 0;
    int len = source.Length;
    for(i = 0; i + vecCount < len; i = i + vecCount)
    {
        var items = new int[vecCount];
        for (int k = 0; k < vecCount; k++)
        {
            items[k] = source[i + k];
        }
        yield return new Vector<int>(items);
    }
    var remaining = new int[vecCount];
    for (int j = i, k =0; j < len; j++, k++)
    {
        remaining[k] = source[j];
    }
    yield return new Vector<int>(remaining);
}
私有静态IEnumerable GetSimdVector(短[]源代码)
{
int vecCount=Vector.Count;
int i=0;
int len=源文件的长度;
对于(i=0;i+vecCount
正如@mike z所指出的,您需要确保您处于发布模式,并且以64位为目标,否则支持SIMD的编译器RuyJIT将无法工作(目前,它仅在64位体系结构上受支持)。 此外,在执行前进行检查始终是一种良好的做法,使用:

Vector.IsHardwareAccelerated;
另外,在创建向量之前,不需要先使用for循环来创建数组。您只需使用
向量(int[]array,int index)
构造函数从原始源数组创建向量即可

yield return new Vector<int>(source, i);
我的性能只提高了1.5倍。考虑到操作的简单性,对于这个非常特殊的情况,仍然是一个改进


不用说,矢量化版本需要大型阵列来克服每次迭代中创建
新Vector()
所带来的开销。

您是否在64位(即释放模式)和64位(确保您没有使用任何32位CPU)上运行优化?您可以通过验证SIMD是否正在使用。就是这样。没有在64位模式下运行。迈克,如果你发布一个答案,我可以这样标记
var items = new int[vecCount];
for (int k = 0; k < vecCount; k++)
{
    items[k] = source[i + k];
}
yield return new Vector<int>(items);
private static int GetSIMDVectorsSum(int[] source)
    {
        int vecCount = Vector<int>.Count;
        int i = 0;
        int end_state = source.Length;

        Vector<int> temp = Vector<int>.Zero;


        for (; i < end_state; i += vecCount)
        {
            temp += new Vector<int>(source, i);

        }

        return Vector.Dot<int>(temp, Vector<int>.One);


    }
private static int no_vec_sum(int[] vals)
{
    int end = vals.Length;
    int temp = 0;

    for (int i = 0; i < end; i++)
    {
        temp += vals[i];
    }
    return temp;
}