저는 현재 매우 큰 이미지 볼륨을 가지고있는 프로젝트에 참여하고 있습니다. 이 볼륨은 매우 빠르게 처리해야합니다 (더하기, 빼기, 임계 값 등). 또한 볼륨의 대부분이 너무 커서 이벤트가 시스템의 메모리에 맞지 않습니다. 그런 이유로 나는 볼륨과 이미지 데이터를 호스트하는 추상 볼륨 클래스 (VoxelVolume)를 생성하고 볼륨에 대한 정규 수학 연산을 수행 할 수 있도록 연산자를 오버로드합니다. 따라서 두 개의 추가 질문이 stackoverflow에 추가 될 질문이 두 개 더 열렸습니다.C# 일반 배열 및 수학 연산
여기 내 첫 번째 질문입니다. 내 볼륨은 플로트 배열 데이터 만 포함 할 수있는 방식으로 구현되지만 대부분의 포함 데이터는 UInt16 이미지 소스에서 가져온 것입니다. 볼륨에 대한 작업 만 float 배열 이미지를 만들 수 있습니다.
나는 클래스가 다음처럼 보였다 같은 볼륨 구현 시작했을 때 :public abstract class VoxelVolume<T>
{
...
}
을하지만 그때 나는 연산자를 오버로드 또는 반환 값이 더 복잡 얻을 것이라는 점을 깨달았다. 예제는 다음과 같습니다
...
public static VoxelVolume<T> operator+(VoxelVolume<T> A, VoxelVolume<T> B)
{
...
}
이의는, 그럼에도 불구하고 나는 이미지를 포함하는 배열의 다른 유형을 가지고 내가 위에서 설명한 문제를 극복 할 수 가정 해 봅시다 :
public abstract class VoxelVolume<T>
{
...
public static VoxelVolume<T> Import<T>(param string[] files)
{
}
}
도 추가 두 개의 오버로드 운영자가 더 복잡 것 데이터. 플로트 할 볼륨에 타입을 고정 했으므로 두 개의 이미지 볼륨 어레이의 내용을 추가 할 때 안전하지 않은 조작을 할 수 있습니다. 여기서 몇 가지 스레드를 읽고 웹을 둘러 보았지만 다른 유형의 배열 두 개를 빠르게 추가하려는 경우 수행 할 작업에 대한 실제 설명이 없습니다. 불행히도 C#에서는 기본 데이터 유형의 크기를 계산할 수 없기 때문에 제네릭에 대한 모든 수학 연산을 수행 할 수 없습니다. 물론 C++/CLR을 사용하여이 문제를 해결할 수도 있지만 현재까지 내가 한 모든 작업은 일을하지 않고도 32 비트 및 64 비트에서 실행됩니다. C++/CLR로 전환하는 것이 (특정 플랫폼 (32 비트)에 바인딩되어 있다는 잘못된 생각이 들었을 때 나에게 기분이 좋았다.) 애플리케이션을 다른 플랫폼 (64 비트)에서 실행할 때 어셈블리를 두 개 컴파일해야했다. 사실입니까?
빠른 시일 내에 두 가지 유형의 배열 두 개를 어떻게 추가 할 수 있습니까? C# 개발자가이 문제에 대해 생각해 본 것이 사실입니까? 다른 언어 (C# -> C++)로 전환하는 것이 옵션이 아닌 것 같습니다.
나는 그것이 작동한다면 그것은 좋은 것입니다하지만 단순히이 작업
float []A = new float[]{1,2,3};
byte []B = new byte[]{1,2,3};
float []C = A+B;
을 수행하는 것이 가능하고 불필요한 아니라는 것을 알고 있습니다. 나는 다음과 같은 한려고 내 솔루션 : 위의 코드는 매우 정확하지 않은 경우
public static class ArrayExt
{
public static unsafe TResult[] Add<T1, T2, TResult>(T1 []A, T2 []B)
{
// Assume the length of both arrays is equal
TResult[] result = new TResult[A.Length];
GCHandle h1 = GCHandle.Alloc (A, Pinned);
GCHandle h2 = GCHandle.Alloc (B, Pinned);
GCHandle hR = GCHandle.Alloc (C, Pinned);
void *ptrA = h1.ToPointer();
void *ptrB = h2.ToPointer();
void *ptrR = hR.ToPointer();
for (int i=0; i<A.Length; i++)
{
*((TResult *)ptrR) = (TResult *)((T1)*ptrA + (T2)*ptrB));
}
h1.Free();
h2.Free();
hR.Free();
return result;
}
}
는 서하십시오, 나는 C#을 편집기를 사용하지 않고 그것을 썼다. 그런 해결책이 생각보다 위에 보이나요? 제가 실수를했거나 불완전하게 몇 가지를 설명했는지 물어보십시오. 당신의 도움이
마틴
이 질문을 삭제하고 비 커뮤니티 위키로 다시 요청해야합니다. (먼저, '편집'을 클릭하고 소스를 복사하십시오.) – SLaks
CW가 아니어도 다시 요청할 필요는 없습니다. –