Задать вопрос
@SergeySerge11

Как запускаются потоки в группах на gpu, какие есть гарантии, может ли поток из другой группы запустится раньше времени?

Почему код введет себя не правильно, Ну тут же не может быть ни какой ошибки.
Использую библиотеку ILGPU.
Как такое вообще может быть? Не знаю где вообще инфу найти, голову разбил искав ошибки даже не предполагая что такое может быть.
Простая функция на вход поступает массив значений, и массив смещений для заполняя этим значением буффера, который должен обновляется каждой другой порцией потоков, то есть у каждого потока должен быть свой регион памяти этого буфера, как только все 1024 потока завершились в группе то следуюие 1024 уже этот буфер по своему перезапишут, но походу кто-то запускается раньше времени.
Ни каких конфликтов быть не может, так как в примере все смещения линейны. Все максимально просто.


internal partial class Program
 {
 
     public static void kernel (ArrayView1D<int, Stride1D.Dense> values, ArrayView1D<int, Stride1D.Dense> offsets, ArrayView1D<int,Stride1D.Dense>  buffer )
 
     {
         int index = Grid.GlobalLinearIndex;
         if (index >= values.Length)
             return;
         int value=values [index]; 
         int offset =   offsets[Group.IdxX];  
         for (int i=0; i <10; i++)  // рисую 10 значений, на выводе на экран, 
         {
            // все потоки запущенные в этой группе работают с этим буффером
            //  следующая группа поток затрет этот буфер.  
             buffer[offset + i] =  value; 
                //Atomic.Exchange(ref buffer[offset + i], value);  одновременного доступа не может быть. 
         }     
           //Grroup.Barrier();  да и это не помогает.
     }


     unsafe static void Main   (string[] args)
     {    //for (; ; ){ не всегда наблюдается.
         using var ctx = Context.CreateDefault();
         using var a = ctx.CreateCudaAccelerator(0);
         var k =a.LoadStreamKernel<ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>, ArrayView1D<int, Stride1D.Dense>>(kernel);
  

         int n =11114000 ;
         int sizeGroup = 1024 ;
         int numThreads = (n + sizeGroup - 1) / sizeGroup;

         var valsBuf   =a.Allocate1D<int>(n);
         var resultBuf =a.Allocate1D<int>(sizeGroup*10);
         var offsetsdBuf =a.Allocate1D<int>(sizeGroup);


         int[]arrVals=Enumerable.Range(0, n).ToArray(); 
         int sum = 0;
         int [] offsets = new int[sizeGroup ];
         for (int i = 0; i < offsets.Length; i++)
         {
             offsets[i] =sum;
             sum += 10;
         } 
         resultBuf.MemSetToZero();
         valsBuf.CopyFromCPU(arrVals);
         offsetsdBuf.CopyFromCPU(offsets); 


         k(new(numThreads, sizeGroup),valsBuf.View, offsetsdBuf.View, resultBuf.View);
         a.Synchronize(); 

         Console.WriteLine();
         int[] res = resultBuf.GetAsArray1D();
         for (int i = 0; i < sizeGroup; i++)
         {
             Console.WriteLine();
             int v = res[i * 10];
//  вывожу все линии должны из одинаковых 10 чисел, 
             for (int j = 0; j < 10; j++)
             {
                 // if(res[i * 10 + j] != v) 
                        //throw new("ERRRRR");
                     Console.Write("{0,8} ", res[i * 10  + j]);
             }
         }
         Console.WriteLine();
         // 1021952  1021952  1021952  1021952  1021952  1021952  1021952  1020928  1017856  1020928
         // 1021953  1021953  1021953  1021953  1021953  1021953  1021953  1020929  1017857  1020929 
         // ....................
         // 1023105  1022081  1022081  1022081  1023105  1023105  1023105  1008769  1023105  1022081
         /// почему тут не 10 элементов к ряду ? А порой все норм, случайность 
     } 
 }
  • Вопрос задан
  • 626 просмотров
Подписаться 3 Сложный 2 комментария
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы