Почему код введет себя не правильно, Ну тут же не может быть ни какой ошибки.
Использую библиотеку 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 элементов к ряду ? А порой все норм, случайность
}
}