• 飞腾2000+按通道分配内存


    1、背景介绍

    飞腾2000+64核处理器,全芯片有八个NUMA结点0~7,每个NUMA结点有8个cores和一个MCU,在NUMA系统中,每个CPU都可以访问本地和远程内存。本地内存位于与CPU相同的节点上,提供了非常低的内存访问延迟。远程内存位于不同的节点,必须通过互连访问。从软件的角度来看,这个远程内存可以用相同的方式使用本地内存;它是完全缓存相干的。访问它需要更长的时间,因为互连比节点的本地内存总线增加了更多的延迟。

    为了使用户空间程序更容易优化NUMA配置,用户可以通过libnuma中提供的库函数进行指定的处理器和内存资源的分配,这里介绍按通道分配内存,更多内容查看这篇文章:libnuma详解(A NUMA API for LINUX)_叶子心情你不懂的博客-程序员宅基地_libnuma - 程序员宅基地

    2、代码示例

    1. /*
    2. ============================================================================
    3. Name : test_mem.c
    4. Author : 111
    5. Version :
    6. Copyright : Your copyright notice
    7. Description : Hello World in C, Ansi-style
    8. ============================================================================
    9. */
    10. #include
    11. #include
    12. #include
    13. #include
    14. #include
    15. #include
    16. #include
    17. #include
    18. #include
    19. #include
    20. #include
    21. #include
    22. #include
    23. #include
    24. #define __USE_GNU
    25. #include
    26. #include
    27. #include
    28. #define COUNTNUMBER 100
    29. #define SRC_NODE 0
    30. #define DST_NODE 7
    31. static void timespec_sub(struct timespec *t1, const struct timespec *t2) {
    32. assert(t1->tv_nsec >= 0);
    33. assert(t1->tv_nsec < 1000000000);
    34. assert(t2->tv_nsec >= 0);
    35. assert(t2->tv_nsec < 1000000000);
    36. t1->tv_sec -= t2->tv_sec;
    37. t1->tv_nsec -= t2->tv_nsec;
    38. if (t1->tv_nsec >= 1000000000) {
    39. t1->tv_sec++;
    40. t1->tv_nsec -= 1000000000;
    41. } else if (t1->tv_nsec < 0) {
    42. t1->tv_sec--;
    43. t1->tv_nsec += 1000000000;
    44. }
    45. }
    46. int main( )
    47. {
    48. int rc;
    49. int i;
    50. int src_index,dst_index;
    51. char *src = NULL;
    52. char *dst = NULL;
    53. char *psrc = NULL;
    54. char *pdst = NULL;
    55. struct timespec ts_start, ts_end;
    56. int size = 65536;
    57. double timec = 0;
    58. unsigned int src_node=SRC_NODE;
    59. unsigned int dst_node=DST_NODE;
    60. double speed=0;
    61. for(src_index=0;src_index<8;src_index++)
    62. {
    63. for(dst_index=0;dst_index<8;dst_index++)
    64. {
    65. src_node=src_index;
    66. dst_node=dst_index;
    67. size=0x40000000;
    68. src=(char *)numa_alloc_onnode(size,src_node);
    69. dst=(char *)numa_alloc_onnode(size,dst_node);
    70. psrc = src;
    71. pdst = dst;
    72. rc = clock_gettime(CLOCK_MONOTONIC, &ts_start);
    73. for(i=0;i
    74. {
    75. memcpy(pdst, psrc, size);
    76. }
    77. rc = clock_gettime(CLOCK_MONOTONIC, &ts_end);
    78. numa_free(src,size);
    79. numa_free(dst,size);
    80. printf("copy data from node%d to node%d total count is %d\n",src_node,dst_node,COUNTNUMBER);
    81. timespec_sub(&ts_end, &ts_start);
    82. /* display passed time, a bit less accurate but side-effects are accounted for */
    83. timec = 1.0* ts_end.tv_sec * 1000000 + ts_end.tv_nsec / 1000;
    84. //printf("timec is %lf\n",timec);
    85. speed=1.0*size/(timec/1000000/COUNTNUMBER);
    86. //printf("CLOCK_MONOTONIC reports %ld.%09ld seconds (total) for copy %d 1000 times\n", ts_end.tv_sec, ts_end.tv_nsec,size);
    87. printf("CLOCK_MONOTONIC reports average time %.2lf GB/s for copy %d times %d GB\n",
    88. speed/(1024*1024*1024), COUNTNUMBER, size / (1024*1024*1024));
    89. }
    90. }
    91. return EXIT_SUCCESS;
    92. }

    针对DDR8通道的情况,上述代码进行了按通道的内存分配,并进行了拷贝计算,统计出不同通道之间数据拷贝的速率。

  • 相关阅读:
    muc和soc的区别与联系
    【通过】华为OD机试:判读字符串子序列
    无锡合全药业有限公司新药制剂开发服务及制剂生产项目中消防应急照明和疏散指示系统的应用
    前端高度变化实现过渡动画
    03 基础张量操作_3
    【自动化测试】——robotframework实战(二)新建测试用例
    【计算机毕业设计】Java ssm 高校运动会管理系统(开题+源码+论文)
    Docker、Jenkins、Harbor 构建镜像部署 SpringBoot 项目
    CPC训练联盟程序设计夏令营(四)
    【Minecraft开服教程】使用 MCSM 面板一键搭建我的世界服务器,并内网穿透公网远程联机
  • 原文地址:https://blog.csdn.net/jj12345jj198999/article/details/127973355