英创信息技术基于WEC7的多核系统编程方法

windows embedded compact 7(wec7)一个最重要的特性就是对多核处理器的支持(symmetric multi-processing(smp)),esm6802是英创公司推出的基于freescale i.mx6dl双核处理器的高性能工控主板,预装正版wec7嵌入式操作系统,并且内核启用了对smp的支持。在多个程序同时执行的情况下,支持smp的多核系统具有比单处理器更好的性能,因为不同的程序可以在不同的处理器上同时运行,支持smp还可以实现在一个核心上执行硬实时应用程序,而用户界面(ui)或其它应用程序可在另一个核心上运行,以提高系统的效率。
wec7提供了一组处理多核系统上线程和处理器调度的smp api接口函数:
https://msdn.microsoft.com/en-us/library/gg154433(v=winembedded.70).aspx
其中应用程序常用的smp api如下所示:
getcurrentprocessornumber 获取在调用此函数期间当前线程正在运行的处理器
cegetidletimeex 获取指定处理器的空闲时间
cegetprocessaffinity 获取指定进程的进程关联
cegetthreadaffinity 获取指定线程的线程关联
cegettotalprocessors 获取系统中的处理器核心总数
cesetprocessaffinity 为指定的进程设置处理器关联
cesetthreadaffinity 为指定的线程设置处理器关联
默认情况下,wec7系统会自动的将系统负载分配到cpu的所有核心上运行,应用程序不需要做任何设置。但根据不同的应用场景,应用程序也可以利用smp api手动的设置每个进程、每个线程在指定的cpu核心上运行,这里以计算esm6802 i.mx6dl cpu每个核心的负载为例,介绍wec7 smp api的使用方法。
应用程序首先通过cegettotalprocessors函数获取当前系统总的处理器(核心)个数,然后根据cpu核心个数创建相同数量的cpuidlemonitorthread应用线程用于计算cpu负载,在创建线程后通过cesetthreadaffinity函数将所创建的线程固定在指定的cpu核心上运行。cpuidlemonitorthread线程函数在执行时先调用getcurrentprocessornumber函数取得执行当前线程的cpu核,而后再利用cegetidletimeex函数最终计算出每个cpu核心的负载率。完整的例子代码如下:
#includestdafx.h
// time in seconds to run the monitor thread
#defineidle_monitor_time 100
handle g_hmonitorthreads[4];
uint32cpuidlemonitorthread(pvoid pcontext)
{
uint32 ncpuid = ((uint32*)pcontext)[0];
uint32 nruntime = ((uint32*)pcontext)[1];
uint32 nidlebefore, nidleafter, nidlediff, nidlepercent;
uint32 nreturn = error_success;
large_integer pcbefore = { 0, 0 };
large_integer pcafter = { 0, 0 };
large_integer diff;
large_integer freq;
retailmsg(1, (l[cpu%d] run monitor thread for %d seconds\r\n, ncpuid, nruntime));
// the processor number is a 1-based index.
queryperformancefrequency(&freq);
while(nruntime > 0)
{
ncpuid = getcurrentprocessornumber();
cegetidletimeex(ncpuid, (lpdword)&nidlebefore);
queryperformancecounter(&pcbefore);
sleep(2000);
queryperformancecounter(&pcafter);
cegetidletimeex(ncpuid, (lpdword)&nidleafter);
diff.quadpart = (pcafter.quadpart - pcbefore.quadpart) * 1000 / freq.quadpart;
nidlediff = nidleafter - nidlebefore;
nidlepercent = nidlediff / 20;
retailmsg(1, (l[cpu%d] sleep: 2000 ms (actual:%d ms) idle: %03d ms (cpu%d = %d%%)\r\n,
ncpuid, diff.lowpart, nidlediff, ncpuid, 100 - nidlepercent));
nruntime--;
}
setevent(g_hmonitorthreads[ncpuid - 1]);
returnnreturn;
}
intwinapi winmain(hinstance hinstance,
hinstance hprevinstance,
lptstr lpcmdline,
int ncmdshow)
{
uint32 ncpucount;
uint32 ntemp = 0;
uint32 i;
uint32 nparam[8] = { 1, idle_monitor_time, 2, idle_monitor_time, 3, idle_monitor_time, 4,idle_monitor_time };
ncpucount = cegettotalprocessors();
for(i = 0; i < ncpucount; i++)
g_hmonitorthreads[i] = createevent(null, true, false, null);
ntemp = 1;
cesetthreadaffinity(getcurrentthread(), 1);
for(i = 1; i < ncpucount; i++)
{
handle hthread = createthread(
null,
0,
(lpthread_start_routine)cpuidlemonitorthread,
&nparam[i * 2],
create_suspended,
null);
if(null != hthread)
{
cesetthreadaffinity(hthread, i + 1);
resumethread(hthread);
sleep(0);
closehandle(hthread);
ntemp++;
}
else
{
setevent(g_hmonitorthreads[i]);
}
}
cpuidlemonitorthread(&nparam[0]);
sleep(2000);
for(i = 0; i < ncpucount; i++)
waitforsingleobject(g_hmonitorthreads[i], (idle_monitor_time + 5) * 1000);
retailmsg(1, (l[cpuload] number of cpus monitored: %d\r\n, ntemp));
return0;
}

智慧城市安全系统的必要性
零线接地会怎么样
年度爆品!NANK南卡新款真无线蓝牙耳机NANK lite首销!
企业如何从IT资产的可见性中受益
什么是boot loader?
英创信息技术基于WEC7的多核系统编程方法
C++中mutable关键字详解与实战
为什么共识算法对于加密货币至关重要
外媒:中国欲打造自己的安全智能手机
华为P10闪存门最新消息:魅族李楠抨击华为P10,用野菜换了韭菜
如何评估工业网络安全解决方案?
开关电源中高频磁性元件设计常见错误概念辨析
美国发现同位素抑制散热法,可提高太阳能电池发电效率
中国联通联合3Glasses 推动5GXR生态联盟
焊锡丝焊接时出现拉尖连焊怎么办
平升电子:4G DTU替换GPRS DTU需要注意哪些问题?
瑞萨推出用于工业以太网通信的RZ/N2L微处理器
驱动电机产品价格走低 市场机会依旧大
马化腾:腾讯不做芯片 国产芯片距离腾讯很远?
禹山CDOM传感器的测定方法及原理