Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.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# 尝试使用Alea GPU查找大素数_C#_.net_Cuda_Gpgpu_Aleagpu - Fatal编程技术网

C# 尝试使用Alea GPU查找大素数

C# 尝试使用Alea GPU查找大素数,c#,.net,cuda,gpgpu,aleagpu,C#,.net,Cuda,Gpgpu,Aleagpu,当我尝试使用Alea GPU查找第100000个素数时出现异常。如果我试图找到一个较小的素数,例如第10000个素数,那么这个算法工作得很好 我使用的是Alea v3.0.4、NVIDIA GTX 970、Cuda 9.2驱动程序 我是GPU编程新手。任何帮助都将不胜感激 long[] primeNumber = new long[1]; // nth prime number to find int n = 100000; // find the 100,000th prime number

当我尝试使用Alea GPU查找第100000个素数时出现异常。如果我试图找到一个较小的素数,例如第10000个素数,那么这个算法工作得很好

我使用的是Alea v3.0.4、NVIDIA GTX 970、Cuda 9.2驱动程序

我是GPU编程新手。任何帮助都将不胜感激

long[] primeNumber = new long[1]; // nth prime number to find
int n = 100000; // find the 100,000th prime number
var worker = Gpu.Default; // GTX 970 CUDA v9.2 drivers
long count = 0;

worker.LongFor(count, n, x =>
{                
    long a = 2;
    while (count < n)
    {
        long b = 2;
        long prime = 1;
        while (b * b <= a)
        {
            if (a % b == 0)
            {
                prime = 0;
                break;
            }
            b++;
        }
        if (prime > 0)
        {
            count++;
        }
        a++;
    }

    primeNumber[0] = (a - 1);
}
);

你的代码看起来不正确。这里给出了一个并行for循环方法(LongFor),Alea将生成“n”个线程,索引“x”用于标识线程编号。例如,一个简单的例子,比如(0,n,x=>a[x]=x);使用“x”初始化带有{0,1,2,…,n-1}的[]。但是,内核代码在代码中的任何地方都不使用“x”。因此,您运行相同的代码“n”次,完全没有差异。那么为什么要在GPU上运行呢?我想你们要做的是在线程“x”中计算“x”是否是素数。手头有结果时,设置bool prime[x]=true或false。然后,在所有这些之后,在内核中添加一个sync调用,然后使用单个线程(例如,x==0)进行测试,以遍历prime[]并从数组中选择最大的prime。否则,“素数[0]=(a-1);”会有很多冲突通过GPU上的n个线程。我无法想象你怎么会得到正确的结果。最后,您可能希望确保使用某种Alea调用时,prime[]永远不会复制到GPU或从GPU复制。但是,我不知道你在Alea是怎么做到的。编译器可能足够聪明,知道prime[]只在内核代码中使用。

您的代码看起来不正确。这里给出了一个并行for循环方法(LongFor),Alea将生成“n”个线程,索引“x”用于标识线程编号。例如,一个简单的例子,比如(0,n,x=>a[x]=x);使用“x”初始化带有{0,1,2,…,n-1}的[]。但是,内核代码在代码中的任何地方都不使用“x”。因此,您运行相同的代码“n”次,完全没有差异。那么为什么要在GPU上运行呢?我想你们要做的是在线程“x”中计算“x”是否是素数。手头有结果时,设置bool prime[x]=true或false。然后,在所有这些之后,在内核中添加一个sync调用,然后使用单个线程(例如,x==0)进行测试,以遍历prime[]并从数组中选择最大的prime。否则,“素数[0]=(a-1);”会有很多冲突通过GPU上的n个线程。我无法想象你怎么会得到正确的结果。最后,您可能希望确保使用某种Alea调用时,prime[]永远不会复制到GPU或从GPU复制。但是,我不知道你在Alea是怎么做到的。编译器可能足够聪明,知道prime[]只在内核代码中使用。

谢谢!我不知道“n”是生成的线程数。这就解释了为什么我的屏幕会黑屏几秒钟:并行运行的计算太多了。我采纳了你的建议,使用埃拉托斯琴斯算法的筛子来确定x是否为素数,并在上面发布了一个有效的解决方案。再次感谢!非常感谢。我不知道“n”是生成的线程数。这就解释了为什么我的屏幕会黑屏几秒钟:并行运行的计算太多了。我采纳了你的建议,使用埃拉托斯琴斯算法的筛子来确定x是否为素数,并在上面发布了一个有效的解决方案。再次感谢!
static void Main(string[] args)
    {
        var devices = Device.Devices;

        foreach (var device in devices)
        {
            Console.WriteLine(device.ToString());                                
        }

        while (true)
        {
            Console.WriteLine("Enter a number to check if it is a prime number:");

            string line = Console.ReadLine();
            long checkIfPrime = Convert.ToInt64(line);

            Stopwatch sw = new Stopwatch();
            sw.Start();
            bool GPUisPrime = GPUIsItPrime(checkIfPrime+1);
            sw.Stop();

            Stopwatch sw2 = new Stopwatch();
            sw2.Start();
            bool CPUisPrime = CPUIsItPrime(checkIfPrime+1);
            sw2.Stop();

            Console.WriteLine($"GPU: is {checkIfPrime} prime? {GPUisPrime} Time Elapsed: {sw.ElapsedMilliseconds.ToString()}");
            Console.WriteLine($"CPU: is {checkIfPrime} prime? {CPUisPrime} Time Elapsed: {sw2.ElapsedMilliseconds.ToString()}");
        }            
    }        

    [GpuManaged]
    private static bool GPUIsItPrime(long n)
    {
        //Sieve of Eratosthenes Algorithm
        bool[] isComposite = new bool[n];
        var worker = Gpu.Default; 
        worker.LongFor(2, n, i =>
        {
            if (!(isComposite[i]))
            {
                for (long j = 2; (j * i) < isComposite.Length; j++)
                {
                    isComposite[j * i] = true;
                }
            }
        });
        return !isComposite[n-1];
    }

    private static bool CPUIsItPrime(long n)
    {
        //Sieve of Eratosthenes Algorithm
        bool[] isComposite = new bool[n];

        for (int i = 2; i < n; i++)
        {
            if (!isComposite[i])
            {
                for (long j = 2; (j * i) < n; j++)
                {
                    isComposite[j * i] = true;
                }
            }
        }

        return !isComposite[n-1];
    }