Код ниже является расширением C-Python.Этот код берет входной буфер непрерывных необработанных байтов (для моего приложения - "блоки" необработанных байтов, где 1 блок = 128 байтов), а затем обрабатывает эти байты в 2-байтовые "выборки", помещая результат в товар .Возвращенная структура - это просто буфер, обработанный в целые числа Python.
Вот 2 основные функции:
unpack_block (items, items_offset, buffer, buffer_offset, samples_per_block, sample_bits);
Затем цикл проходит через каждый образец в элементах и затем преобразует каждый образец в Python Int.
PyList_SET_ITEM (result, index, PyInt_FromLong (items [index]));
unsigned int num_blocks_per_thread, num_samples_per_thread, num_bytes_per_thread;
unsigned int thread_id, p;
unsigned int n_threads, start_index_bytes, start_index_blocks, start_index_samples;
items = malloc(num_samples*sizeof(unsigned long));
assert(items);
#pragma omp parallel\
default(none)\
private(num_blocks_per_thread, num_samples_per_thread, num_bytes_per_thread, d, j, thread_id, n_threads, start_index_bytes, start_index_blocks, start_index_samples)\
shared(samples_per_block, num_blocks, buffer, bytes_per_block, sample_bits, result, num_samples, items)
{
n_threads = omp_get_num_threads();
num_blocks_per_thread = num_blocks/n_threads;
num_samples_per_thread = num_samples/n_threads;
num_bytes_per_thread = num_blocks_per_thread*samples_per_block*2/n_threads;
thread_id = omp_get_thread_num();
start_index_bytes = num_bytes_per_thread*thread_id;
start_index_blocks = num_blocks_per_thread*thread_id;
start_index_samples = num_samples_per_thread*thread_id;
for (d=0; d<num_blocks_per_thread; d++) {
unpack_block(items, start_index_samples+d*samples_per_block, buffer, start_index_blocks + d*bytes_per_block, samples_per_block, sample_bits);
}
}
result = PyList_New(num_samples);
assert(result);
//*THIS WOULD ALSO SEEM RIPE FOR MULTITHREADING*
for (p=0; p<num_samples; p++) {
PyList_SET_ITEM(result, p, PyInt_FromLong( items[p] ));
}
free(items);
free(buffer);
return result;
}
Скорость просто ужасна и намного меньше, чем я ожидаю от многопоточности.У меня может возникнуть проблема с ложным разделением, когда потоки записывают данные в разные блоки массива items , хотя каждый поток обрабатывает только взаимоисключающие блоки одного и того же массива.
Фундаментальный вопрос для меня: как правильно многопоточно обрабатывать отдельный элемент массива, а затем выводить результат для каждого элемента во второй массив «result».Я выполняю это дважды с помощью двух своих функций.
Любые идеи, решения или способы оптимизации будут великолепны.Спасибо!