This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
大家好、
可能有些人已经注意到、我正在尝试(也很困难)使用 OpenMP 在 TMDSEVM6678LE 评估 DSP 模块上获得更好的速度性能(我知道 OMP 的内容现在正在休假。 我可能也会在本月晚些时候将此主题提请他们注意)。
之前、我启动了一个名为 Compiler/TMDSEVM6678的转换线程:OpenMP 堆管理 API 的用途是什么? 我在这里讨论了使用 OpenMP 与串行模式相比时运行缓慢的问题。
而且,非常棒的建议是使用 MSMC RAM 作为 DDR3的一部分来获得更好的速度,因为所有线程都可以同时访问 MSMC,这实际上是非常有帮助的,这要归功于他的宝贵意见。
根据建议、我开始创建一个简单的基准测试、以便在使用和不使用 OMP 的情况下比较和对比 MSMC 与 DDR3。 在下面的示例中,我使用 Memory_alloc (NULL,...)创建了两个大小相同的缓冲区,一个是从 MSMC 分配的,另一个是从 DDR3堆分配的。 。
我对具有和不具有 OMP 的两个缓冲器的每个元素进行简单的数学运算。 下面是针对4个 OMP/NOOMP DDR3/MSMC 组合中每个组合所采用的时钟周期表:
1)显然、当 不使用 OMP 时、MSMC 在 char、float、double 和 long double 方面的工作速度高达5倍。 我只是想知道为什么只有这些数据类型?!!
2) 2)为什么使用 OpenMP 仍然较慢、而 MSMC 应该同时由每个内核访问?
请告诉我我还可以做些什么,以便从 OpenMP 中获益。
如果您对编码有疑问或批评、我会非常高兴听到您的评论。
我可能会在本月晚些时候将此主题提请本论坛注意。
此致、
基准 C 代码(白板.c)
#include #include #include #include #include #include #include #include #include #include typedef unsigned long long dt_uint64; //typedef char buum_datatype; //typedef short buum_datatype; //tyedef int buum_datatype; typedef float buff dataype; //typedef double buff_datatype; //typedef long double buff_datatype; // MSMC 上的缓冲区#pragma DATA_SECTION (MSMC_bufSec、".MSMC_bufSec") #pragma DATA_ALIGN (MSMC_buffer、128) #define Bbuffer*(40 buffer1024) USC_datatype ;mSMC_buffer* main_chu_chu_chu_chu_chu_chu_bapn;// ma_ma_cher_cher* out_chor_chu_chu_buf printf ("--=程序启动=-\n"); TSCH = 0;TSCL = 0; dT_uint64 t_start、t_end; ERROR_Block EB; ERROR_INIT (&EB); int blocksize = 256; // NOOMP,MSMC 上的缓冲器 T_start =_itoll (TSCH、TSCL); for (int j = 0;j < BUFLEN;j++){ MSMC_buff [j]= 1+(MSMC_buff [j]/2*3-50)/2*3-50; } T_end =_itoll (TSCH、TSCL); printf ("NOOMP MSMC 缓冲区处理时间:%llu \n"、t_end - t_start); T_start =_itoll (TSCH、TSCL); // OMP,MSMC #pragma omp 并行 num_threads (8)上的缓冲器 { #pragma omp for for (int j = 0;j < BUFLEN;j++){ // putchar ('M');putchar ('0'+ omp_get_thread_num ()); MSMC_buff [j]= 1+(MSMC_buff [j]/2*3-50)/2*3-50; } } T_end =_itoll (TSCH、TSCL); printf ("OMP MSMC 缓冲区处理时间:%llu \n"、t_end - t_start); DDR_buff = Memory_alloc (NULL、BUFLEN* sizeof (buff 数据类型)、128、&EB); if (!DDR_buff){ printf ("无法从堆中分配 DDR_buff \n"); 退出(1); } //无 OMP,DDR 上的缓冲器 T_start =_itoll (TSCH、TSCL); for (int j = 0;j < BUFLEN;j++){ DDR_buff [j]= 1+(DDR_buff [j]/2*3-50)/2*3-50; } T_end =_itoll (TSCH、TSCL); printf ("NOOMP DDR 缓冲区处理时间:%llu \n"、t_end - t_start); // OMP,DDR 上的缓冲器 T_start =_itoll (TSCH、TSCL); #pragma omp parallel num_threads (8) { #pragma omp for for (int j = 0;j < BUFLEN;j++){ DDR_buff [j]= 1+(DDR_buff [j]/2*3-50)/2*3-50; } } T_end =_itoll (TSCH、TSCL); printf ("OMP DDR 缓冲区处理时间:%llu \n"、t_end - t_start); Memory_free (NULL、DDR_buff、BUFLEN*sizeof (buff 数据类型)); printf ("--=程序结束=-\n"); }
omp_config.cfg
/********* //* 段映射 */ ********* /var program = xdc.useModule('xdc.cfg.Program'); program.sectMap[".args"] = new Program.SectionSpec (); program.sectMap[".bss"] = new Program.SectionSpec (); program.sectMap[".cinit"] = new Program.SectionSpec (); program.sectMap[".cio"] = new Program.SectionSpec (); program.sectMap[".const"] = new Program.SectionSpec (); program.sectMap[".data"] = new Program.SectionSpec (); program.sectMap[".far"] = new Program.SectionSpec (); program.sectMap[".fardata"] = new Program.SectionSpec (); program.sectMap[".neardata"]= new Program.SectionSpec (); program.sectMap[".rodata"] = new Program.SectionSpec (); program.sectMap[".stack"] = new Program.SectionSpec (); program.sectMap[".switch"] = new Program.SectionSpec (); program.sectMap[".sysmem"] = new Program.SectionSpec (); program.sectMap[".text"] = new Program.SectionSpec (); //必须将这些段放在核心本地存储 器 program.sectMap[".args"].loadSegment 中 ="DDR3"; program.sectMap[".cio"].loadSegment ="L2SRAM"; // 在// OpenMP 中,以下数据段中的变量可能会被“共享”。 这些段必须放置在共享存储器中。 program.sectMap[".bss"].loadSegment ="DDR3"; program.sectMap[".cinit"].loadSegment ="DDR3"; program.sectMap[".const"].loadSegment ="DDR3"; program.sectMap[".data"].loadSegment ="DDR3"; program.sectMap[".far"].loadSegment ="DDR3"; program.sectMap[".fardata"].loadSegment ="DDR3"; program.sectMap[".neardata"].loadSegment ="DDR3"; program.sectMap[".rodata"].loadSegment ="DDR3"; program.sectMap[".sysmem"].loadSegment ="DDR3"; //内核共享的代码段-放置在共享存储器中以避免复制 program.sectMap[".switch"].loadSegment = program.platform.codeMemory; program.sectMap[".text"].loadSegment ="MSMCSRAM"; PRINT (" program.platform.codeMemory ="、program.platform.codeMemory); //调整默认堆栈的大小并将其放置在 L2SRAM var deviceName = String (Program.cpu.deviceName); // if (deviceName.search("DRA7XX")=-1){program.stack = 0x20000;} // if (deviceName.search("DRA7XX")=-1){program.stack = 256*1024;} //在串行模式下工作 // if (deviceName.search("DRA7XX")=-1){program.stack = 330*1024;} if (deviceName.search("DRA7XX")=-1){program.stack = 330*1024;} // if (deviceName.search("DRA7XX")=-1){program.stack = 512*1024;} 否则 {program.stack = 0x8000;} program.sectMap[".stack"].loadSegment ="L2SRAM";//在串行模式下工作256KB .stack // program.sectMap[".stack"].loadSegment ="MSMCSRAM";//在 OpenMP 中不起作用 //由于没有参数传递给 main,因此将.args 大小设置为0 program.argSize = 0; /******** /* OpenMP 运行时配置*/******** / use_OpenMP = true; 如果(use_OpenMP){ //在编译中包含 OMP 运行时 var ompSettings = xdc.useModule("ti.runtime.openmp.Settings"); //如果应用使用 BIOS 组件或依赖 BIOS 组件则设置为 true ompSettings.usingRtsc = true; 如果(ompSettings.usingRtsc) { /*为 BIOS 配置 OpenMP *- OpenMP* configureCores (masterCoreId、numberofCoresInRuntime) * 配置主内核的 ID 和内核数 * 运行时可用。 * VAR OpenMP = xdc.useModule('ti.runtime.ompbios.OpenMP'); //配置主内核的索引和可用内核的数量 //到运行时。 内核是连续的。 OpenMP*主 CoreIdx = 0; //根据器件设置内核数 如果 (deviceName.search("DRA7XX")!=-1){OpenMP*= 2;} 否则,如果(deviceName.search("6670")!=-1){ OpenMP*= 4;} 否则,如果(deviceName.search("6657")!=-1){ OpenMP*= 2;} 否则,如果(deviceName.search("K2L")!=-1){ OpenMP*= 4;} 其他 { OpenMP*= 8;} //拉入 Platform.XDC 中描述的内存范围以配置运行时 VAR DDR3 = Program.cpu.memoryMap["DDR3"]; VAR DDR3_NC = Program.cpu.memoryMap["DDR3_NC"; VAR MSMC = Program.cpu.memoryMap["MSMCSRAM"]; var msmcNcVirt= Program.cpu.memoryMap["OMP_MSMC_NC_virt"]; var msmcNcPhy = Program.cpu.memoryMap["OMP_MSMC_NC_PHY"]; //使用内存范围信息初始化运行时间 if (deviceName.search("DRA7XX")=-1){ OpenMP* msmcBase = MSMC.base OpenMP* msmcSize = MSMC.len; OpenMP* msmcNoCacheVirtualBase = msmcNcVirt.base; OpenMP* msmcNoCacheVirtualSize = msmcNcVirt.len; OpenMP*(msmcNoCachePhysicalBase)= msmcNcPhy.base; //OpenMP*分配堆栈= true; //OpenMP*分配标准版从 HeapSize = 4*330*1024; } 其他 { OpenMP*分配堆栈= true; OpenMP*分配堆栈 FromHeapSize = 0x010000; OpenMP* HASMsmc =错误; OpenMP*版 NoCacheBase = DDR3_NC.base; OpenMP*版。ddrNoCacheSize = DDR3_NC.len; } OpenMP*版 = DDR3.base; OpenMP*文件大小 = DDR3.len; //使用 HeapOMP 配置内存分配 // HeapOMP 句柄 //- BIOS 组件发出的内存分配请求(内核本地内存) //-使用 IPC 模块启用共享内存分配 //从同一堆中分配内存的多个内核-由 malloc 使用 if (deviceName.search("DRA7XX")=-1){ 打印("deviceName.search(\"DRA7XX\")=-1") VAR HeapOMP = xdc.useModule('ti.runtime.ompbios.HeapOMP'); //必须为 IPC 初始化共享区域0 VAR sharedRegionId = 0; //内核本地堆的大小 VAR localHeapSize = 0x8000; //所有内核共享的堆的大小 // var sharedHeapSize = 0x08000000; var sharedHeapSize =(512-32-22)*1024*1024; //初始化共享区域并在 DDR3存储器区域中创建堆 VAR SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion'); SharedRegion.setEntryMeta (sharedRegionId、 {base:dr3.base、 Len:sharedHeapSize、 ownerProId:OpenMP*。masterCoreIdx、 高速缓冲启用:true、 createHeap:true、 IsValid:true、 名称:"DDR3_SR0"、 }); //配置和设置 HeapOMP HeapOMP.configure (sharedRegionId、localHeapSize); /* var HeapTrack = xdc.useModule('ti.sysbios.heaps.HeapTrack'); var heapTrackParams = new HeapTrack.Params; heapTrackParams.heap = HeapOMP; var myHeapTracker = HeapTrack.create (heapTrackParams); *} 其他 { OpenMP.useIpcSharedHeap = false; OpenMP*分配本地 HeapSize = 0x8000 OpenMP*分配共享 HeapSize = 0x00800000 } VAR 启动= xdc.useModule('xdc.runtime.Startup'); startup.lastFxns.$add ('&_TI_omp_initialize_rtsc_mode'); } 否则 { /*调整堆的大小。 必须将其放置在共享存储器中* program.heap = sharedHeapSize; } //不使用 openmp }否则{ var BIOS = xdc.useModule('ti.sysbios.BIOS'); BIOS.heapSize =(512-32-22)*1024*1024; Program.sectMap["systemHeap"]= new Program.SectionSpec (); Program.sectMap["systemHeap"].loadSegment="DDR3"; BIOS.heapSection ="systemHeapSect"; var BIOS = xdc.useModule('ti.sysbios.BIOS'); print ("BIOS.heapSize= Program.sectMap[".msmc_bufSec"];"MSm100k.pru.csSize ="100k.cpupru.r";var BIOS ="systemHeapk.cpu.cpuat")
生成日志
aK **为项目 arK_cpplab 构建配置调试****"c:\\ti\\ccs920\\ccs\\utils\\bin\\gmake.exe"所有调用:xDCtools "C:/ti/ccs920/xdctools_3_60_01_27_core/xs --xdcpath="C:/ti/openmp_dsp_c667x_2_06_03_00/packages;C:/ti/ipc_3_50_04_08/packages;C:/ti/openmp_dsp_c667x_2_06_03_00/packages/ti/runtime/openmp/platforms /Debug/configPkg;C:ti;C:/ti/bios_6_76_03_01/packages;" xdctools -config.p .c .c .t 包、因为/ti/pdk_c667x_2_0_16/packages ti.runtime.openmp.platforms.evm6678 -config.t /ti/ccs920/ccs/tools/compiler/ti-cgt-c6000_8.3.6 正在为软件包 configPkg 生成接口(因为 package/package.xdc.inc 比 package.XDC 旧)... 从 package/cfg/omp_config_pe66.cfg 配置 omp_config.xe66 ... program.platform.codeMemory = MSMCSRAM deviceName.search("DRA7XX")=-1 BIOS.heapSize = 4096 为器件配置 OpenMP 运行时:TMS320C6678 正在生成自定义 ti.SYSBIOS 库 makefile ... 链接库 ti.drv.qms:./lib/c66/ti.drv.qmss.ae66 链接库 ti.csl:./lib/c6678/c66/release/ti.csl.ae66 正在开始构建库源... 制作 C:/Users/Feng-laptop/workspace_v9_2_1/ark_cpplab/src/sysbios/sysbios.ae66 ... 已完成库构建。 cle66软件包/cfg/omp_config_pe66.c…… 完工建筑:omp_config.cfg "c:/ti/ccs920/ccs/tools/compiler/ti-cgt-c6000_8.3.6/bin/cl6x /Debug/configPkg/compiler.opt /ti/openmp_dsp_c667x_2_06_03_00/packages/ti/runtime/openmp "-mv6600 -include_path="C:/ti/ccs920/ccs/tools/compiler/ti-cgt-c6000_8.3.6/include /ti/ccs920/ccs/tools/compiler/ti-cgt-c6000_8.3.6/bin/cl6x -include_path="C:/ti/openmp_dsp_c667x_2_06_03_00/packages/ti/runtime/openmp /ti/ccs920/ccs/tools/compiler/ti-cgt-c6000_8.3.6/include "-c99 -g -no_warnes--diag_warning=225 --include_wrap=off --display_error_number --cmd_file="_make_warnese-cn/msp_clocks=-tid_clocks=-tid_tid_clocks=-tid_dl_dlpine_tid_clocks=-tid_dlpet_dlpet_ctrab_dlpet_cep_ctrap_clocks=-dlpet_dl_dlpet_cep_clocks=-tid_dlpet_tid_tid_clocks -tid_iptid_ctrap_clocks=tid_clocks=tid_iptid_tid_iptid_iptid_clus-tid_clus_iptines=tid_dl_clus-tid_ctrap_clus-tag_ diag_warning=225 --diag_wrap=off --display_error_number -z -m"Debug/arK_cpplab.map"-i"C:/ti/ccs920/ccs/tools/compiler/ti-cgt-c6000_8.3.6/lib /ti/bios_6_76_02_02/packages/ti/targets/rts6000/lib/boot.ae66 /src/ipc/ipc.ae66 -i"C:/ti/ccs920/ccs/tools/compiler/ti-cgt-c6000_8.3.6/include /ti/bios_6_76_02_02/packages/ti/targets/rts6000/lib/ti.targets.rts6000.ae66 /src/sysbios/sysbios.ae66 -i"Debug/lib"--reread_libs --warn_wrap=off --display_error_number ---"libar_explor_line.xml_linkg-l_lineb/link/dlpintrab.dlpines"-/Debug/configPkg/linker.cmd -l.link_exctrab.dlpines"-/src/sysbios/sysbios.ae66 -l.dlpac/dlp_excab.dlpines"-/src/utils/utils.ae66 -dlp_exctrab.iptics"-l.iptex-l.ipticl.iptex-l.iptex-l.iptex_ex-l.ip "./Debug/configPkg/linker.cmd、第118行:警告#10068-D:不匹配段 警告#10247-D:在不使用段规范的情况下创建输出段".tbss" 警告#10247-D:在不使用段规范 的情况下创建输出段".tdata"-=构建完成! =-**** 构建完成****
您好、冯、
OMP 专家目前不在办公室,将在他返回办公室后答复。
雷克斯