gpt4 book ai didi

c# - 4 片 bytearray 使用多线程进行比较

转载 作者:太空宇宙 更新时间:2023-11-03 21:56:02 26 4
gpt4 key购买 nike

我被项目的第二阶段困住了:将一个 byte[] 拆分为 4 个切片(以加载 QuadCore I5 CPU),然后对每个切片在每个内核上启动一个线程(比较任务)。

原因是试图加速两个相同大小的字节数组之间的比较我该如何线程?

    [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int memcmp(byte[] b1, byte[] b2, long count);




class ArrayView<T> : IEnumerable<T>
{
private readonly T[] array;
private readonly int offset, count;
public ArrayView(T[] array, int offset, int count)
{
this.array = array; this.offset = offset; this.count = count;
}
public int Length { get { return count; } }
public T this[int index] {
get { if (index < 0 || index >= this.count)
throw new IndexOutOfRangeException();
else
return this.array[offset + index]; }
set { if (index < 0 || index >= this.count)
throw new IndexOutOfRangeException();
else
this.array[offset + index] = value; }
}
public IEnumerator<T> GetEnumerator()
{
for (int i = offset; i < offset + count; i++)
yield return array[i];
}
IEnumerator IEnumerable.GetEnumerator()
{
IEnumerator<T> enumerator = this.GetEnumerator();
while (enumerator.MoveNext())
{
yield return enumerator.Current;
}
}
}




public void CopmarArrSlice()
{

byte[] LoadedArr = File.ReadAllBytes("testFileCompare2Scr.bmp");

int LoddArLn = OrgArr.Length;
int range = (LoddArLn / 4) - LoddAremainder;
int divisionremain = LoddArLn - (range * 4);

ArrayView<byte> LddP1 = new ArrayView<byte>(OrgArr, 0, range);
ArrayView<byte> LddP2 = new ArrayView<byte>(OrgArr, p1.Length, range);
ArrayView<byte> LddP3 = new ArrayView<byte>(OrgArr, (p1.Length + p2.Length), range);
ArrayView<byte> LddP4 = new ArrayView<byte>(OrgArr, (p1.Length + p2.Length + p3.Length), range + divisionremain);


if (AreEqual(LddP1, CapturedP1)) ....Do Somthing

}


public bool AreEqual(byte[] a, byte[] b)
{
if (a == b)
return true;
if (a == null || b == null)
return false;
if (a.Length != b.Length)
return false;
return memcmp(a, b, a.Length) == 0;
}


CopmarArrSlice();

在这种情况下,如何使用 AreEqual(使用 memcmp)将其与使用 4 线程/Parallelism 进行比较,以计算每个 CpuCore

最佳答案

我编写了一个尽可能利用多核的函数,但它似乎受到 p/invoke 调用的严重影响。我认为这个版本只有在测试非常大的数组时才有意义。

static unsafe class NativeParallel
{
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int memcmp(byte* b1, byte* b2, int count);

public static bool AreEqual(byte[] a, byte[] b)
{
// The obvious optimizations
if (a == b)
return true;
if (a == null || b == null)
return false;
if (a.Length != b.Length)
return false;

int quarter = a.Length / 4;
int r0 = 0, r1 = 0, r2 = 0, r3 = 0;
Parallel.Invoke(
() => {
fixed (byte* ap = &a[0])
fixed (byte* bp = &b[0])
r0 = memcmp(ap, bp, quarter);
},
() => {
fixed (byte* ap = &a[quarter])
fixed (byte* bp = &b[quarter])
r1 = memcmp(ap, bp, quarter);
},
() => {
fixed (byte* ap = &a[quarter * 2])
fixed (byte* bp = &b[quarter * 2])
r2 = memcmp(ap, bp, quarter);
},
() => {
fixed (byte* ap = &a[quarter * 3])
fixed (byte* bp = &b[quarter * 3])
r3 = memcmp(ap, bp, a.Length - (quarter * 3));
}
);
return r0 + r1 + r2 + r3 == 0;
}
}

在大多数情况下,它实际上比优化的安全版本慢。

static class SafeParallel
{
public static bool AreEqual(byte[] a, byte[] b)
{
if (a == b)
return true;
if (a == null || b == null)
return false;
if (a.Length != b.Length)
return false;

bool b1 = false;
bool b2 = false;
bool b3 = false;
bool b4 = false;
int quarter = a.Length / 4;
Parallel.Invoke(
() => b1 = AreEqual(a, b, 0, quarter),
() => b2 = AreEqual(a, b, quarter, quarter),
() => b3 = AreEqual(a, b, quarter * 2, quarter),
() => b4 = AreEqual(a, b, quarter * 3, a.Length)
);
return b1 && b2 && b3 && b4;
}

static bool AreEqual(byte[] a, byte[] b, int start, int length)
{
var len = length / 8;
if (len > 0)
{
for (int i = start; i < len; i += 8)
{
if (BitConverter.ToInt64(a, i) != BitConverter.ToInt64(b, i))
return false;
}
}
var remainder = length % 8;
if (remainder > 0)
{
for (int i = length - remainder; i < length; i++)
{
if (a[i] != b[i])
return false;
}
}
return true;
}
}

关于c# - 4 片 bytearray 使用多线程进行比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12252955/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com