【发布时间】:2019-07-12 17:54:36
【问题描述】:
下面的代码是一个 C-Python 扩展。此代码采用连续原始字节的输入 缓冲区(对于我的应用程序,原始字节的“块”,其中 1 个块 = 128 个字节),然后将这些字节处理为 2 个字节的“样本”,将结果项目。返回的结构只是处理成python整数的缓冲区。
以下是两个主要功能:
unpack_block(items, items_offset, buffer, buffer_offset, samples_per_block, sample_bits);
然后循环遍历 items 中的每个样本,然后将每个样本转换为 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 数组的不同块,即使每个线程只处理同一数组的互斥块。
对我来说一个基本问题是:如何正确地多线程处理单个数组的每个元素,然后将每个元素的结果输出到第二个“结果”数组中。我用我的两个函数执行了两次。
任何想法、解决方案或优化方法都会很棒。谢谢!
【问题讨论】:
标签: python c multithreading openmp