Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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
C#埃拉托什尼误解_C#_Multithreading_Primes - Fatal编程技术网

C#埃拉托什尼误解

C#埃拉托什尼误解,c#,multithreading,primes,C#,Multithreading,Primes,我有两个用Eratosthenes筛生成素数的函数,一个使用简单循环,另一个使用任务在多个线程上运行计算 由于在使用线程时需要锁定值列表,所以我假设线程版本不会比正常版本快。但是经过一些测试,普通版本似乎比线程版本差6倍左右 更奇怪的是,当一次只使用一个任务时,它比普通版本快6倍。 我错过了什么 代码如下: 公共静态列表UsualPrimesGenerator(int n) { if(n

我有两个用Eratosthenes筛生成素数的函数,一个使用简单循环,另一个使用任务在多个线程上运行计算

由于在使用线程时需要锁定值列表,所以我假设线程版本不会比正常版本快。但是经过一些测试,普通版本似乎比线程版本差6倍左右

更奇怪的是,当一次只使用一个任务时,它比普通版本快6倍。 我错过了什么

代码如下:

公共静态列表UsualPrimesGenerator(int n)
{
if(n<0)
返回新列表();
List res=新列表();
对于(int i=2;ip!=i2&&p%i2==0);
}
});
}
}
对于(int i=0;i
n=100000的时间测试结果:

Usual Prime Generator: 2732ms
9592 Primes found
Magic Prime Generator: 397ms
9592 Primes found

存在差异的原因是,在简单的解决方案中要进行更多的迭代。如果将循环更改为:

for (int i = 2; i * 2 <= n; i++)
{
    res.RemoveAll(p => p != i && p % i == 0);
}
我没有检查正确性,但我想这不是你的问题。 此外,您的测量方法可以改进,如上所述。但这不是本案的问题所在

循环中带有计数器的完整代码

class Program
{
    private const int n = 100000;
    
    static void Main(string[] args)
    {
        MagicPrimesGenerator(n, 12);
        MagicPrimesGenerator(n, 12);
        MagicPrimesGenerator(n, 12);
        MagicPrimesGenerator(n, 12);
        UsualPrimesGenerator(n);
        UsualPrimesGenerator(n);
        UsualPrimesGenerator(n);
        UsualPrimesGenerator(n);
        
        var sw = new Stopwatch();
        sw.Start();

        sw.Reset();
        sw.Start();
        MagicPrimesGenerator(n, 1);
        Console.WriteLine($"B: Magic Prime Generator: {sw.ElapsedMilliseconds} ms");
        
        sw.Reset();
        sw.Start();
        UsualPrimesGenerator(n);
        Console.WriteLine($"A: Usual Prime Generator: {sw.ElapsedMilliseconds} ms");
    }
    
    
    public static List<int> UsualPrimesGenerator(int n)
    {
        int count = 0;
        if (n < 0)
            return new List<int>();
        List<int> res = new List<int>();
        for (int i = 2; i < n; i++) res.Add(i);

        for (int i = 2; i * 2 <= res.Count; i++)
        {   
            res.RemoveAll(p => p != i && p % i == 0);
            count++;
        }
        
        Console.Write("usual iteration count ");
        Console.WriteLine(count);
        return res;
    }

    public static List<int> MagicPrimesGenerator(int n, int nbTasks)
    {
        if (nbTasks <= 0)
            throw new ArgumentException("Nbthread must be positive");

        var threads = new Task[nbTasks];
        int count = 0;

        List<int> primes = new List<int>();
        for (int i = 2; i <= n; i++)
            primes.Add(i);

        for (int i = 2; i * 2 <= primes.Count; i++)
        {
            if (threads[i % nbTasks] == null)
            {
                var i2 = i;
                threads[i % nbTasks] = Task.Run(() =>
                {
                    lock (primes)
                    {
                        primes.RemoveAll(p => p != i2 && p % i2 == 0);
                        count++;
                    }
                });
            }
            else
            {
                threads[i % nbTasks].Wait();
                var i2 = i;
                threads[i % nbTasks] = Task.Run(() =>
                {
                    lock (primes)
                    {
                        primes.RemoveAll(p => p != i2 && p % i2 == 0);
                        count++;
                    }
                });
            }
        }

        for (int i = 0; i < nbTasks; i++)
        {
            if (threads[i] != null)
                threads[i].Wait();
        }
        
        Console.Write("magic iteration count ");
        Console.WriteLine(count);

        return primes;
    }
}
类程序
{
私人建筑单位n=100000;
静态void Main(字符串[]参数)
{
magicpromesgenerator(n,12);
magicpromesgenerator(n,12);
magicpromesgenerator(n,12);
magicpromesgenerator(n,12);
通常情况下,发电机(n);
通常情况下,发电机(n);
通常情况下,发电机(n);
通常情况下,发电机(n);
var sw=新秒表();
sw.Start();
sw.Reset();
sw.Start();
magicpromesgenerator(n,1);
Console.WriteLine($“B:Magic Prime Generator:{sw.elapsedmillesons}ms”);
sw.Reset();
sw.Start();
通常情况下,发电机(n);
WriteLine($“A:常用的素数生成器:{sw.elapsedmillesons}ms”);
}
公共静态列表UsualPrimesGenerator(int n)
{
整数计数=0;
if(n<0)
返回新列表();
List res=新列表();
对于(int i=2;ip!=i2&&p%i2==0);
计数++;
}
});
}
}
对于(int i=0;i
之所以存在差异,是因为您在简单的解决方案中进行了更多的迭代。如果将循环更改为:

for (int i = 2; i * 2 <= n; i++)
{
    res.RemoveAll(p => p != i && p % i == 0);
}
我没有检查正确性,但我想这不是你的问题。 此外,您的测量方法可以改进,如上所述。但这不是本案的问题所在

循环中带有计数器的完整代码

class Program
{
    private const int n = 100000;
    
    static void Main(string[] args)
    {
        MagicPrimesGenerator(n, 12);
        MagicPrimesGenerator(n, 12);
        MagicPrimesGenerator(n, 12);
        MagicPrimesGenerator(n, 12);
        UsualPrimesGenerator(n);
        UsualPrimesGenerator(n);
        UsualPrimesGenerator(n);
        UsualPrimesGenerator(n);
        
        var sw = new Stopwatch();
        sw.Start();

        sw.Reset();
        sw.Start();
        MagicPrimesGenerator(n, 1);
        Console.WriteLine($"B: Magic Prime Generator: {sw.ElapsedMilliseconds} ms");
        
        sw.Reset();
        sw.Start();
        UsualPrimesGenerator(n);
        Console.WriteLine($"A: Usual Prime Generator: {sw.ElapsedMilliseconds} ms");
    }
    
    
    public static List<int> UsualPrimesGenerator(int n)
    {
        int count = 0;
        if (n < 0)
            return new List<int>();
        List<int> res = new List<int>();
        for (int i = 2; i < n; i++) res.Add(i);

        for (int i = 2; i * 2 <= res.Count; i++)
        {   
            res.RemoveAll(p => p != i && p % i == 0);
            count++;
        }
        
        Console.Write("usual iteration count ");
        Console.WriteLine(count);
        return res;
    }

    public static List<int> MagicPrimesGenerator(int n, int nbTasks)
    {
        if (nbTasks <= 0)
            throw new ArgumentException("Nbthread must be positive");

        var threads = new Task[nbTasks];
        int count = 0;

        List<int> primes = new List<int>();
        for (int i = 2; i <= n; i++)
            primes.Add(i);

        for (int i = 2; i * 2 <= primes.Count; i++)
        {
            if (threads[i % nbTasks] == null)
            {
                var i2 = i;
                threads[i % nbTasks] = Task.Run(() =>
                {
                    lock (primes)
                    {
                        primes.RemoveAll(p => p != i2 && p % i2 == 0);
                        count++;
                    }
                });
            }
            else
            {
                threads[i % nbTasks].Wait();
                var i2 = i;
                threads[i % nbTasks] = Task.Run(() =>
                {
                    lock (primes)
                    {
                        primes.RemoveAll(p => p != i2 && p % i2 == 0);
                        count++;
                    }
                });
            }
        }

        for (int i = 0; i < nbTasks; i++)
        {
            if (threads[i] != null)
                threads[i].Wait();
        }
        
        Console.Write("magic iteration count ");
        Console.WriteLine(count);

        return primes;
    }
}
类程序
{
私人建筑单位n=100000;
静态void Main(字符串[]参数)
{
magicpromesgenerator(n,12);
magicpromesgenerator(n,12);
magicpromesgenerator(n,12);
magicpromesgenerator(n,12);
通常情况下,发电机(n);
通常情况下,发电机(n);
通常情况下,发电机(n);
通常情况下,发电机(n);
var sw=新秒表();
sw.Start();
sw.Reset();
sw.Start();
magicpromesgenerator(n,1);
Console.WriteLine($“B:Magic Prime Generator:{sw.elapsedmillesons}ms”);
sw.Reset();
sw.Start();
通常情况下,发电机(n);
WriteLine($“A:常用的素数生成器:{sw.elapsedmillesons}ms”);
}
公共静态列表UsualPrimesGenerator(int n)
{
整数计数=0;
if(n<0)
返回新列表();
List res=新列表();
对于(int i=2;ip!=i2&&p%i2==0);
计数++;
}
});
}
}
对于(int i=0;i
这些不是
线程
。这些是
任务
。线程和任务。是的,对不起,错了,我知道