多线程并行操作下的内存访问问题

sinat_33314857 2016-10-07 04:48:03
继上一个问题“多线程如何实现对多维数组的写操作”,得到了老师们的解答,很受教!
现在做的项目涉及到大数据的实时处理,所以用到多线程提速,实现对很多块数据的处理。但是在使用中,发现串行处理一个数据块的时间0.006s,而对于16个数据块16个线程下,每个线程处理一块数据的时间有0.05s;考虑到线程调用的时间消耗外(线程提前创建好,所以不考虑线程创建消耗),不清楚多线程并行处理下其他的时间开销出在啊哪里,相比串行耗时这么多(对16数据块16个线程,并行总时间要低于串行,但提速有限,也只有4倍左右)?
处理过程,对存放处理前、处理后数据块的数组都定义成全局数组a[i][j][k],既然多线程对全局数组a[i][j][k]不同位置的操作没有冲突竞争,那我多余的时间消耗又出在哪里,是在内存这一块吗?
现在一直在调试,没有找到出路,程序优化也进行不下去,希望能得到老师们的指导!
...全文
489 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
sinat_33314857 2016-10-12
  • 打赏
  • 举报
回复
目前这个问题也算是有了不错的结果。赵老师给出的使用Visual Studio Profiler的意见,经过测试,发现是程序的问题,虽然具体问题不清楚,只能通过其他方法找出程序性能瓶颈了。 paschen给出的解释,也做了参考。因为在这里我是用的线程池的方式,发现创建超过核心数目的线程数能够带了较好的结果,具体原因,我还得再翻课本了。 总之,谢谢老师们给出的意见。结贴。
赵4老师 2016-10-09
  • 打赏
  • 举报
回复
建议先通读MSDN中性能分析所有章节。
赵4老师 2016-10-09
  • 打赏
  • 举报
回复
引用 8 楼 sinat_33314857 的回复:
[quote=引用 7 楼 zhao4zhong1 的回复:] 建议先通读MSDN中性能分析所有章节。
赵老师,在MSDN上也看了Visual Studio Profiler的使用,但似乎没有出现我这样的问题,您能够给个解释吗? 当启动性能向导,一段时间后,选择“停止分析”时,出现提示窗口: Microsoft Visual Studio 已停止工作 出现了问题,导致程序停止正常工作。。 然后vs2010软件就直接退出了。问题应该出现在哪里?如何排查?[/quote] 可能只是因为你没安装VS2010的必要补丁SP
sinat_33314857 2016-10-09
  • 打赏
  • 举报
回复
引用 7 楼 zhao4zhong1 的回复:
建议先通读MSDN中性能分析所有章节。


赵老师,在MSDN上也看了Visual Studio Profiler的使用,但似乎没有出现我这样的问题,您能够给个解释吗?
当启动性能向导,一段时间后,选择“停止分析”时,出现提示窗口:
Microsoft Visual Studio 已停止工作
出现了问题,导致程序停止正常工作。。
然后vs2010软件就直接退出了。问题应该出现在哪里?如何排查?
sinat_33314857 2016-10-08
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
无profiler不要谈效率!!尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代!
使用Visual Studio Profiler分析程序性能确实不错,但有个问题是我现在使用的工作电脑在“启动性能向导”时,总是得不出分析结果,在自己的笔记本上用其他程序测试时是可以使用,不知道问题出在哪里?是工作机的Visual Studio 2010配置问题?还是我的程序问题?
赵4老师 2016-10-08
  • 打赏
  • 举报
回复
使用SIMD ? 参考下面:
//SSE2 SIMD example
#include <stdio.h>
#include <intrin.h>
typedef unsigned __int16 WORD;
__declspec(align(32)) WORD x[16];
__declspec(align(32)) WORD y[16];
__inline void histogram_add_Intrinsic_SSE2(const WORD x[16], WORD y[16]) {
  __m128i b2 = _mm_load_si128((__m128i *)&y[8]);
  __m128i b1 = _mm_load_si128((__m128i *) y   );
  __m128i a2 = _mm_load_si128((__m128i *)&x[8]);
  __m128i a1 = _mm_load_si128((__m128i *) x   );

  a1 = _mm_add_epi16(a1, b1);
  a2 = _mm_add_epi16(a2, b2);

  _mm_store_si128((__m128i *)&y[8], a2);
  _mm_store_si128((__m128i *) y   , a1);
}
int main() {
    int i;

    for (i=0;i<16;i++) {
        x[i]=i+1;
        y[i]=8;
    }
    printf("x: ");for (i=0;i<16;i++)  printf("%2hd ",x[i]);printf("\n");
    printf("y: ");for (i=0;i<16;i++)  printf("%2hd ",y[i]);printf("\n");
    histogram_add_Intrinsic_SSE2(x,y);printf("--------------------\n");
    printf("x: ");for (i=0;i<16;i++)  printf("%2hd ",x[i]);printf("\n");
    printf("y: ");for (i=0;i<16;i++)  printf("%2hd ",y[i]);printf("\n");
    return 0;
}
//x:  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16
//y:  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8
//--------------------
//x:  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16
//y:  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
//
赵4老师 2016-10-08
  • 打赏
  • 举报
回复
使用CUDA ?
赵4老师 2016-10-08
  • 打赏
  • 举报
回复
无profiler不要谈效率!!尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代!
sinat_33314857 2016-10-07
  • 打赏
  • 举报
回复
引用 1 楼 paschen 的回复:
多线程的管理也是有开销的,另外如果CPU核心数没那么多,多个线程也只是并发计算而不是并行计算
确实有这个原因。考虑我的电脑16核,而数据块个数远大于16000,如果这样调整:对这16000多数据块(数据块间的数据不相关),每个线程分配1000块,这样,每个线程的负载足够多,这样虽然单个并行线程的处理过程是串行的,但并行处理上应该没问题吧?虽然加速比提高不到16倍,但也不应该只有4倍左右。除了线程管理、调用的开销,内存或者其他方面要考虑吗?(我要处理的数据确实很多)
paschen 2016-10-07
  • 打赏
  • 举报
回复
多线程的管理也是有开销的,另外如果CPU核心数没那么多,多个线程也只是并发计算而不是并行计算

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧