Сообщение Re[13]: 2D-Linq и оптимизация цифровых фильтров - 3 от 04.07.2018 7:52
Изменено 04.07.2018 8:12 vdimas
Re[13]: 2D-Linq и оптимизация цифровых фильтров - 3
Здравствуйте, Sinclair, Вы писали:
S>Можно всё же в студию полное тело метода FourNeighborAverage?
S>Можете, если хотите, сделать его generic с where T: Struct, IArray2d<T>.
Разумеется генерик, ради ж этого всё.
Без студии:
Что здесь "так" в сравнении с твоим вариантом?
Здесь прикладное "знание" об алгоритме содержится в самом алгоритме, вот тут: int x = 1, DX = array.dx — 1.
В твоём же алгоритме такие "знания" необходимо каким-то образом передавать в сам абстрактный индексер.
Мой индексер получается более простым и универсальным — это просто абстракция некоторой матрицы.
Учитывая новый ref-return, можно попробовать пойти еще дальше:
Т.е. пусть Span<T> указывает на "область" длиной в одно значение, т.е. эдакий трюк ввиду того, что новый Core-фреймворк знает конкретно тип Span "в лицо".
Не, знаю, стоит ли напоминать, что в алгоритмах обработки изображений почти всегда присутствует параметр stride, который задаёт "шаг" между строками в физической памяти. Этот параметр можно загнать в конкретную реализацию IArray2d, т.е. можно побить изображение на области в том числе вертикально, т.е. распараллелить работу произвольных алгоритмов.
S>Меня интересует не "индексер" (предоставленный, потенциально, библиотекой), а полный код, который должен писать прикладной программист.
А другой программист должен будет еще этот код читать, верно?
S>Можно всё же в студию полное тело метода FourNeighborAverage?
S>Можете, если хотите, сделать его generic с where T: Struct, IArray2d<T>.
Разумеется генерик, ради ж этого всё.
Без студии:
void FourNeighborAverage<T>(T array) where T : struct, IArray2d<int>
{
for(int y = 1, dy = array.DY - 1; y < dy; y++)
for(int x = 1, dx = array.DX - 1; x < dx; x++)
array[x, y] = array[x-1, y] + array[x+1, y] + array[x, y-1] + array[x, y+1];
}
Что здесь "так" в сравнении с твоим вариантом?
Здесь прикладное "знание" об алгоритме содержится в самом алгоритме, вот тут: int x = 1, DX = array.dx — 1.
В твоём же алгоритме такие "знания" необходимо каким-то образом передавать в сам абстрактный индексер.
Мой индексер получается более простым и универсальным — это просто абстракция некоторой матрицы.
Учитывая новый ref-return, можно попробовать пойти еще дальше:
[cs]
interface IArray2d<T> {
...
ref T this[int x, int y] { get; } // только геттер
}
...
unsafe void FourNeighborAverage(T array) where T : struct, IArray2d<int>
{
int dx = array.DX;
for(int y = 1, dy = array.DY - 1; y < dy; y++) {
fixed(int* current = array[1, y])
fixed(int* end = array[dx, y])
fixed(int* it1 = array[0, y])
fixed(int* it2 = array[2, y])
fixed(int* it3 = array[1, y - 1])
fixed(int* it4 = array[1, y + 1]) {
int* c = current, _1 = it1, _2 = it2, _3 = it3, _4 = it4;
while(c < end)
*c++ = *_1++ + *_2++ + *_3++ + *_4++;
}
}
}
Т.е. пусть Span<T> указывает на "область" длиной в одно значение, т.е. эдакий трюк ввиду того, что новый Core-фреймворк знает конкретно тип Span "в лицо".
Не, знаю, стоит ли напоминать, что в алгоритмах обработки изображений почти всегда присутствует параметр stride, который задаёт "шаг" между строками в физической памяти. Этот параметр можно загнать в конкретную реализацию IArray2d, т.е. можно побить изображение на области в том числе вертикально, т.е. распараллелить работу произвольных алгоритмов.
S>Меня интересует не "индексер" (предоставленный, потенциально, библиотекой), а полный код, который должен писать прикладной программист.
А другой программист должен будет еще этот код читать, верно?
Re[13]: 2D-Linq и оптимизация цифровых фильтров - 3
Здравствуйте, Sinclair, Вы писали:
S>Можно всё же в студию полное тело метода FourNeighborAverage?
S>Можете, если хотите, сделать его generic с where T: Struct, IArray2d<T>.
Разумеется генерик, ради ж этого всё.
Без студии:
Что здесь "так" в сравнении с твоим вариантом?
Здесь прикладное "знание" об алгоритме содержится в самом алгоритме, вот тут: int x = 1, DX = array.dx — 1.
В твоём же алгоритме такие "знания" необходимо каким-то образом передавать в сам абстрактный индексер.
Мой индексер получается более простым и универсальным — это просто абстракция некоторой матрицы.
Учитывая новый ref-return, можно попробовать пойти еще дальше:
Не, знаю, стоит ли напоминать, что в алгоритмах обработки изображений почти всегда присутствует параметр stride, который задаёт "шаг" между строками в физической памяти. Этот параметр можно загнать в конкретную реализацию IArray2d, т.е. можно побить изображение на области в том числе вертикально, т.е. распараллелить работу произвольных алгоритмов.
S>Меня интересует не "индексер" (предоставленный, потенциально, библиотекой), а полный код, который должен писать прикладной программист.
А другой программист должен будет еще этот код читать, верно?
S>Можно всё же в студию полное тело метода FourNeighborAverage?
S>Можете, если хотите, сделать его generic с where T: Struct, IArray2d<T>.
Разумеется генерик, ради ж этого всё.
Без студии:
void FourNeighborAverage<T>(T array) where T : struct, IArray2d<int>
{
for(int y = 1, dy = array.DY - 1; y < dy; y++)
for(int x = 1, dx = array.DX - 1; x < dx; x++)
array[x, y] = array[x-1, y] + array[x+1, y] + array[x, y-1] + array[x, y+1];
}
Что здесь "так" в сравнении с твоим вариантом?
Здесь прикладное "знание" об алгоритме содержится в самом алгоритме, вот тут: int x = 1, DX = array.dx — 1.
В твоём же алгоритме такие "знания" необходимо каким-то образом передавать в сам абстрактный индексер.
Мой индексер получается более простым и универсальным — это просто абстракция некоторой матрицы.
Учитывая новый ref-return, можно попробовать пойти еще дальше:
[cs]
interface IArray2d<T> {
...
ref T this[int x, int y] { get; } // только геттер
}
...
unsafe void FourNeighborAverage(T array) where T : struct, IArray2d<int>
{
int dx = array.DX;
for(int y = 1, dy = array.DY - 1; y < dy; y++) {
fixed(int* current = array[1, y])
fixed(int* end = array[dx, y])
fixed(int* it1 = array[0, y])
fixed(int* it2 = array[2, y])
fixed(int* it3 = array[1, y - 1])
fixed(int* it4 = array[1, y + 1]) {
int* c = current, _1 = it1, _2 = it2, _3 = it3, _4 = it4;
while(c < end)
*c++ = *_1++ + *_2++ + *_3++ + *_4++;
}
}
}
Не, знаю, стоит ли напоминать, что в алгоритмах обработки изображений почти всегда присутствует параметр stride, который задаёт "шаг" между строками в физической памяти. Этот параметр можно загнать в конкретную реализацию IArray2d, т.е. можно побить изображение на области в том числе вертикально, т.е. распараллелить работу произвольных алгоритмов.
S>Меня интересует не "индексер" (предоставленный, потенциально, библиотекой), а полный код, который должен писать прикладной программист.
А другой программист должен будет еще этот код читать, верно?