-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
1477 lines (1398 loc) · 306 KB
/
Copy pathatom.xml
File metadata and controls
1477 lines (1398 loc) · 306 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[JinXing’s blog]]></title>
<link href="/atom.xml" rel="self"/>
<link href="jiaojinxing.github.io/"/>
<updated>2017-01-12T06:53:04.455Z</updated>
<id>jiaojinxing.github.io/</id>
<author>
<name><![CDATA[jiaojinxing]]></name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title><![CDATA[Hercules TMS570LC43x LaunchPad SylixOS移植记录]]></title>
<link href="jiaojinxing.github.io/2017/01/12/Hercules-TMS570LC43x-LaunchPad-SylixOS%E7%A7%BB%E6%A4%8D%E8%AE%B0%E5%BD%95/"/>
<id>jiaojinxing.github.io/2017/01/12/Hercules-TMS570LC43x-LaunchPad-SylixOS移植记录/</id>
<published>2017-01-12T01:53:20.000Z</published>
<updated>2017-01-12T06:53:04.455Z</updated>
<content type="html"><![CDATA[<p>Hercules TMS570LC43x LaunchPad是TI官方出的TMS570LC43x芯片DEMO板:<br><a href="http://www.ti.com/tool/launchxl2-570lc43" target="_blank" rel="external">http://www.ti.com/tool/launchxl2-570lc43</a></p>
<p>TMS570LC43x使用ARM Cortex-R5核心,主频300MHz,<br>有MPU、CACHE、FPU,没有MMU,Flash有4MB,RAM只有512KB,近日成功跑起SylixOS,记录一下移植过程以备忘。</p>
<h2 id="硬件连接">硬件连接</h2><p>使用一USB转TTL模块连接LaunchPad有SCI3,如下图:<br><img src="/img/Hercules-TMS570LC43x-LaunchPad/Image 22.png" alt="Image 22.png"></p>
<h2 id="sylixos-base裁减">sylixos-base裁减</h2><p>目前只编译libsylixos,sylixos-base的makefile如下:<br><figure class="highlight elixir"><table><tr><td class="code"><pre><span class="line"><span class="constant">COMPONENTS </span>= \</span><br><span class="line">libsylixos \</span><br><span class="line"></span><br><span class="line"><span class="symbol">all:</span> <span class="variable">$(</span><span class="constant">COMPONENTS)</span></span><br><span class="line"> <span class="variable">@for</span> target <span class="keyword">in</span> <span class="variable">$(</span><span class="constant">COMPONENTS)</span>; <span class="keyword">do</span> make -<span class="constant">C </span><span class="variable">$$</span>target all -j <span class="number">16</span>; done</span><br><span class="line"></span><br><span class="line"><span class="symbol">clean:</span> <span class="variable">$(</span><span class="constant">COMPONENTS)</span></span><br><span class="line"> <span class="variable">@for</span> target <span class="keyword">in</span> <span class="variable">$(</span><span class="constant">COMPONENTS)</span>; <span class="keyword">do</span> make -<span class="constant">C </span><span class="variable">$$</span>target clean; done</span><br></pre></td></tr></table></figure></p>
<h2 id="libsylixos裁减">libsylixos裁减</h2><p>libsylixos也需要裁减,libsylixos的makefile,修改BUILD_LITE_TARGET变量值为1,即编译lite版本:<br><figure class="highlight armasm"><table><tr><td class="code"><pre><span class="line"><span class="keyword">BUILD_LITE_TARGET </span>= <span class="number">1</span></span><br></pre></td></tr></table></figure></p>
<p>libsylixos下的libsylixos.mk,去掉:<br><figure class="highlight stylus"><table><tr><td class="code"><pre><span class="line">SylixOS/fs/mtd/mtdcore<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/mtd/linux/bch<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/mtd/linux/strim<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/mtd/nand/nand_base<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/mtd/nand/nand_bbt<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/mtd/nand/nand_bch<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/mtd/nand/nand_ecc<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/mtd/nand/nand_ids<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/mtd/onenand/onenand_base<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/mtd/onenand/onenand_bbt<span class="class">.c</span> \</span><br></pre></td></tr></table></figure></p>
<figure class="highlight stylus"><table><tr><td class="code"><pre><span class="line">SylixOS/fs/yaffs2/yaffs_allocator<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_attribs<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_bitmap<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_checkptrw<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_ecc<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_guts<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_mtdif_multi<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_nameval<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_nand<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_nor<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_packedtags1<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_packedtags2<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_summary<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_sylixos<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_sylixosproc<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_tagscompat<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_tagsmarshall<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_verify<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_yaffs1<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/yaffs_yaffs2<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/direct/yaffscfg<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/direct/yaffsfs<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/direct/yaffs_hweight<span class="class">.c</span> \</span><br><span class="line">SylixOS/fs/yaffs2/direct/yaffs_qsort.c</span><br></pre></td></tr></table></figure>
<p>同时将:<br><figure class="highlight fix"><table><tr><td class="code"><pre><span class="line"><span class="attribute">NET_SRCS </span>=<span class="string"> \</span></span><br></pre></td></tr></table></figure></p>
<p>修改为:<br><figure class="highlight fix"><table><tr><td class="code"><pre><span class="line"><span class="attribute">NO_NET_SRCS </span>=<span class="string"> \</span></span><br></pre></td></tr></table></figure></p>
<p>即不编译mtd、yaffs2、net。</p>
<h2 id="libsylixos配置">libsylixos配置</h2><p>修改的配置项目比较多,这里只罗列重要的几个,如下:</p>
<p>SylixOS\config\cpu\cpu_cfg_arm.h:<br><figure class="highlight stylus"><table><tr><td class="code"><pre><span class="line"><span class="hexcolor">#def</span>ine LW_CFG_ARM_PL330 <span class="number">0</span> <span class="comment">/* 是否允许 PL330 DMA 驱动 */</span></span><br><span class="line"><span class="hexcolor">#def</span>ine LW_CFG_ARM_CACHE_L2 <span class="number">0</span> <span class="comment">/* 是否允许管理 ARM 二级 CACHE */</span></span><br><span class="line"><span class="hexcolor">#def</span>ine LW_CFG_ARM_CACHE_L2_ECC <span class="number">0</span> <span class="comment">/* 是否打开 ARM 二级 CACHE ECC */</span></span><br></pre></td></tr></table></figure></p>
<p>SylixOS\config\kernel\vmm_cfg.h:<br><figure class="highlight stylus"><table><tr><td class="code"><pre><span class="line"><span class="hexcolor">#def</span>ine LW_CFG_VMM_EN <span class="number">0</span> <span class="comment">/* 是否需要对虚拟内存的支持 */</span></span><br></pre></td></tr></table></figure></p>
<p>SylixOS\config\mp\mp_cfg.h:<br><figure class="highlight stylus"><table><tr><td class="code"><pre><span class="line"><span class="hexcolor">#def</span>ine LW_CFG_SMP_EN <span class="number">0</span> <span class="comment">/* 是否需要系统对多处理器支持 */</span></span><br></pre></td></tr></table></figure></p>
<h2 id="HALCoGen使用">HALCoGen使用</h2><p>使用HALCoGen新建一个工程:</p>
<p>CPU按图选择,TOOLS 使用 GCC:<br><img src="/img/Hercules-TMS570LC43x-LaunchPad/Image 3.png" alt="Image 3.png"></p>
<p>使能 GIO、SCI3、RTI驱动:<br><img src="/img/Hercules-TMS570LC43x-LaunchPad/Image 4.png" alt="Image 4.png"></p>
<p>配置SCI3的管脚复用:<br><img src="/img/Hercules-TMS570LC43x-LaunchPad/Image 5.png" alt="Image 5.png"></p>
<p>配置SCI3的波特率为115200:<br><img src="/img/Hercules-TMS570LC43x-LaunchPad/Image 6.png" alt="Image 6.png"></p>
<p>配置SCI3的PORT:<br><img src="/img/Hercules-TMS570LC43x-LaunchPad/Image 7.png" alt="Image 7.png"></p>
<p>配置异常向量表:<br><img src="/img/Hercules-TMS570LC43x-LaunchPad/Image 8.png" alt="Image 8.png"></p>
<p>配置各处理器模式的堆栈空间大小:<br><img src="/img/Hercules-TMS570LC43x-LaunchPad/Image 9.png" alt="Image 9.png"></p>
<p>配置GIO PORTB BIT6为输出:<br><img src="/img/Hercules-TMS570LC43x-LaunchPad/Image 10.png" alt="Image 10.png"></p>
<h2 id="BSP编写">BSP编写</h2><p>创建 bsp,模板使用arm-none,名字为bsparmr5。</p>
<p>将 HALCoGen 生成的代码放到 SylixOS/driver/HCG 目录。</p>
<p>将 config.ld 的内容清空,因为链接脚本不需要配置了。</p>
<p>将 SylixOS/bsp/symbol.c 排除到工程外。</p>
<p>将 SylixOS/bsp/bspMap.h 删除,同时 bspInit.c 不再 include 该头文件。</p>
<p>修改 SylixOS/driver/HCG/source/HL_sys_startup.c:<br><figure class="highlight cpp"><table><tr><td class="code"><pre><span class="line"><span class="comment">/* USER CODE BEGIN (26) */</span></span><br><span class="line"> <span class="function"><span class="keyword">extern</span> <span class="keyword">int</span> <span class="title">bspInit</span><span class="params">(<span class="keyword">void</span>)</span></span>;</span><br><span class="line"> bspInit();</span><br><span class="line"><span class="comment">/* USER CODE END */</span></span><br></pre></td></tr></table></figure></p>
<p>修改 SylixOS/driver/HCG/source/HL<em>sys_core.s文件的_coreInitStackPointer</em>函数,返回前通过cps #19进入SVC模式:<br><figure class="highlight armasm"><table><tr><td class="code"><pre><span class="line"><span class="label">_coreInitStackPointer_</span>:</span><br><span class="line"> <span class="keyword">cps </span> <span class="number">#17</span></span><br><span class="line"> <span class="keyword">ldr </span> <span class="literal">sp</span>, fiqSp</span><br><span class="line"> <span class="keyword">cps </span> <span class="number">#18</span></span><br><span class="line"> <span class="keyword">ldr </span> <span class="literal">sp</span>, irqSp</span><br><span class="line"> <span class="keyword">cps </span> <span class="number">#19</span></span><br><span class="line"> <span class="keyword">ldr </span> <span class="literal">sp</span>, <span class="keyword">svcSp</span><br><span class="line"></span> <span class="keyword">cps </span> <span class="number">#23</span></span><br><span class="line"> <span class="keyword">ldr </span> <span class="literal">sp</span>, abortSp</span><br><span class="line"> <span class="keyword">cps </span> <span class="number">#27</span></span><br><span class="line"> <span class="keyword">ldr </span> <span class="literal">sp</span>, undefSp</span><br><span class="line"> <span class="keyword">cps </span> <span class="number">#31</span></span><br><span class="line"> <span class="keyword">ldr </span> <span class="literal">sp</span>, userSp</span><br><span class="line"> <span class="keyword">cps </span> <span class="number">#19</span> </span><br><span class="line"> <span class="keyword">bx </span> <span class="literal">lr</span></span><br></pre></td></tr></table></figure></p>
<h3 id="链接脚本_SylixOSBSP-ld">链接脚本 SylixOSBSP.ld</h3><p>使用 SylixOS/driver/HCG/source/HL_sys_link.ld 的内容,加入:</p>
<figure class="highlight gherkin"><table><tr><td class="code"><pre><span class="line"> PROVIDE ( end = _ebss );</span><br><span class="line"> PROVIDE ( _end = _ebss );</span><br><span class="line"> </span><br><span class="line">/<span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span></span><br><span class="line"> 内核堆段</span><br><span class="line"><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span><span class="keyword">*</span>/</span><br><span class="line"></span><br><span class="line"> .heap (NOLOAD) : {</span><br><span class="line"> . = ALIGN(8);</span><br><span class="line"> PROVIDE (__heap_start = .);</span><br><span class="line"> </span><br><span class="line"> __heap_end = ORIGIN(RAM) + LENGTH(RAM) - 128;</span><br><span class="line"> PROVIDE (__heap_end = .);</span><br><span class="line"> } > RAM</span><br></pre></td></tr></table></figure>
<h3 id="config-h">config.h</h3><p>内容如下,需要根据芯片的 Flash 和 RAM 的地址、容量来修改:</p>
<figure class="highlight cpp"><table><tr><td class="code"><pre><span class="line"><span class="preprocessor">#<span class="keyword">define</span> BSP_CFG_ROM_BASE (0x00000000)</span></span><br><span class="line"><span class="preprocessor">#<span class="keyword">define</span> BSP_CFG_ROM_SIZE (4 * 1024 * 1024)</span></span><br><span class="line"></span><br><span class="line"><span class="preprocessor">#<span class="keyword">define</span> BSP_CFG_RAM_BASE (0x08000000)</span></span><br><span class="line"><span class="preprocessor">#<span class="keyword">define</span> BSP_CFG_RAM_SIZE (512 * 1024)</span></span><br></pre></td></tr></table></figure>
<h3 id="bsparmr5-mk">bsparmr5.mk</h3><p>关键变量如下:</p>
<figure class="highlight haml"><table><tr><td class="code"><pre><span class="line">LOCAL_INC_PATH := \</span><br><span class="line">-<span class="ruby"><span class="constant">I</span><span class="string">"./SylixOS"</span> \</span><br><span class="line"></span>-<span class="ruby"><span class="constant">I</span><span class="string">"./SylixOS/bsp"</span> \</span><br><span class="line"></span>-<span class="ruby"><span class="constant">I</span><span class="string">"$(WORKSPACE_bsparmr5)/SylixOS\driver\HCG\include"</span></span></span><br></pre></td></tr></table></figure>
<figure class="highlight haml"><table><tr><td class="code"><pre><span class="line">LOCAL_DSYMBOL := \</span><br><span class="line">-<span class="ruby"><span class="constant">D__BOOT_INROM</span>=<span class="number">1</span> \</span><br><span class="line"></span>-<span class="ruby"><span class="constant">D__SYLIXOS_LITE</span>=<span class="number">1</span></span></span><br></pre></td></tr></table></figure>
<p>加入SylixOS/driver/HCG/source/HL_sys_core.s的编译,它需要使用浮点才能编译通过:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ARM_FPU_ASFLAGS = -mfloat-abi=softfp -mfpu=vfpv3</span><br><span class="line"></span><br><span class="line">$(OBJPATH)/$(LOCAL_TARGET_NAME)/SylixOS/driver/HCG/<span class="built_in">source</span>/HL_sys_core.o: ./SylixOS/driver/HCG/<span class="built_in">source</span>/HL_sys_core.s</span><br><span class="line"> @<span class="keyword">if</span> [ ! <span class="operator">-d</span> <span class="string">"<span class="variable">$(dir $@)</span>"</span> ]; <span class="keyword">then</span> \</span><br><span class="line"> mkdir -p <span class="string">"<span class="variable">$(dir $@)</span>"</span>; <span class="keyword">fi</span></span><br><span class="line"> @<span class="keyword">if</span> [ ! <span class="operator">-d</span> <span class="string">"<span class="variable">$(dir $(__DEP)</span>)"</span> ]; <span class="keyword">then</span> \</span><br><span class="line"> mkdir -p <span class="string">"<span class="variable">$(dir $(__DEP)</span>)"</span>; <span class="keyword">fi</span></span><br><span class="line"> $(AS) $(ARM_FPU_ASFLAGS) $($(__TARGET)_ASFLAGS_WITHOUT_FPUFLAGS) -MMD -MP -MF $(__DEP) -c $< -o <span class="variable">$@</span></span><br></pre></td></tr></table></figure>
<h3 id="bspInit-c关键内容">bspInit.c关键内容</h3><p>cortex-r5 同样支持 WFI 指令:<br><figure class="highlight gradle"><table><tr><td class="code"><pre><span class="line"><span class="keyword">static</span> <span class="keyword">VOID</span> halIdleInit (<span class="keyword">VOID</span>)</span><br><span class="line">{</span><br><span class="line"> API_SystemHookAdd(armWaitForInterrupt,</span><br><span class="line"> LW_OPTION_THREAD_IDLE_HOOK); <span class="comment">/* 空闲时暂停 CPU */</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>CACHE 初始化:<br><figure class="highlight objectivec"><table><tr><td class="code"><pre><span class="line"><span class="keyword">static</span> VOID halCacheInit (VOID)</span><br><span class="line">{</span><br><span class="line"> API_CacheLibInit(<span class="built_in">CACHE_COPYBACK</span>, <span class="built_in">CACHE_COPYBACK</span>, ARM_MACHINE_R5); <span class="comment">/* 初始化 CACHE 系统 */</span></span><br><span class="line"> API_CacheEnable(I<span class="built_in">NSTRUCTION_CACHE</span>);</span><br><span class="line"> API_CacheEnable(DATA_<span class="built_in">CACHE</span>); <span class="comment">/* 使能 CACHE */</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>FPU 初始化(使用 VFPv3-d16):<br><figure class="highlight gradle"><table><tr><td class="code"><pre><span class="line"><span class="keyword">static</span> <span class="keyword">VOID</span> halFpuInit (<span class="keyword">VOID</span>)</span><br><span class="line">{</span><br><span class="line"> API_KernelFpuInit(ARM_MACHINE_R5, ARM_FPU_VFPv3);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>没有硬盘,使用 ramfs:<br><figure class="highlight openscad"><table><tr><td class="code"><pre><span class="line">static VOID halStdDirInit <span class="params">(VOID)</span></span><br><span class="line">{</span><br><span class="line"> <span class="comment">/*</span><br><span class="line"> * 没有硬盘,使用 ramfs,并链接到根文件系统的目录</span><br><span class="line"> */</span></span><br><span class="line"> system<span class="params">(<span class="string">"mount -t ramfs 0 /ram"</span>)</span>;</span><br><span class="line"> mkdir<span class="params">(<span class="string">"/ram/boot"</span>, DEFAULT_DIR_PERM)</span>;</span><br><span class="line"> mkdir<span class="params">(<span class="string">"/ram/etc"</span>, DEFAULT_DIR_PERM)</span>;</span><br><span class="line"> mkdir<span class="params">(<span class="string">"/ram/ftk"</span>, DEFAULT_DIR_PERM)</span>;</span><br><span class="line"> mkdir<span class="params">(<span class="string">"/ram/qt"</span>, DEFAULT_DIR_PERM)</span>;</span><br><span class="line"> mkdir<span class="params">(<span class="string">"/ram/lib"</span>, DEFAULT_DIR_PERM)</span>;</span><br><span class="line"> mkdir<span class="params">(<span class="string">"/ram/lib/modules"</span>, DEFAULT_DIR_PERM)</span>;</span><br><span class="line"> mkdir<span class="params">(<span class="string">"/ram/usr"</span>, DEFAULT_DIR_PERM)</span>;</span><br><span class="line"> mkdir<span class="params">(<span class="string">"/ram/usr/lib"</span>, DEFAULT_DIR_PERM)</span>;</span><br><span class="line"> mkdir<span class="params">(<span class="string">"/ram/bin"</span>, DEFAULT_DIR_PERM)</span>;</span><br><span class="line"> mkdir<span class="params">(<span class="string">"/ram/sbin"</span>, DEFAULT_DIR_PERM)</span>;</span><br><span class="line"> mkdir<span class="params">(<span class="string">"/ram/apps"</span>, DEFAULT_DIR_PERM)</span>;</span><br><span class="line"> mkdir<span class="params">(<span class="string">"/ram/home"</span>, DEFAULT_DIR_PERM)</span>;</span><br><span class="line"> mkdir<span class="params">(<span class="string">"/ram/root"</span>, DEFAULT_DIR_PERM)</span>;</span><br><span class="line"> mkdir<span class="params">(<span class="string">"/ram/var"</span>, DEFAULT_DIR_PERM)</span>;</span><br><span class="line"> mkdir<span class="params">(<span class="string">"/ram/tmp"</span>, DEFAULT_DIR_PERM)</span>;</span><br><span class="line"></span><br><span class="line"> symlink<span class="params">(<span class="string">"/ram/boot"</span>, <span class="string">"/boot"</span>)</span>;</span><br><span class="line"> symlink<span class="params">(<span class="string">"/ram/etc"</span>, <span class="string">"/etc"</span>)</span>;</span><br><span class="line"> symlink<span class="params">(<span class="string">"/ram/ftk"</span>, <span class="string">"/ftk"</span>)</span>;</span><br><span class="line"> symlink<span class="params">(<span class="string">"/ram/qt"</span>, <span class="string">"/qt"</span>)</span>;</span><br><span class="line"> symlink<span class="params">(<span class="string">"/ram/lib"</span>, <span class="string">"/lib"</span>)</span>;</span><br><span class="line"> symlink<span class="params">(<span class="string">"/ram/usr"</span>, <span class="string">"/usr"</span>)</span>;</span><br><span class="line"> symlink<span class="params">(<span class="string">"/ram/bin"</span>, <span class="string">"/bin"</span>)</span>;</span><br><span class="line"> symlink<span class="params">(<span class="string">"/ram/sbin"</span>, <span class="string">"/sbin"</span>)</span>;</span><br><span class="line"> symlink<span class="params">(<span class="string">"/ram/apps"</span>, <span class="string">"/apps"</span>)</span>;</span><br><span class="line"> symlink<span class="params">(<span class="string">"/ram/home"</span>, <span class="string">"/home"</span>)</span>;</span><br><span class="line"> symlink<span class="params">(<span class="string">"/ram/root"</span>, <span class="string">"/root"</span>)</span>;</span><br><span class="line"> symlink<span class="params">(<span class="string">"/ram/var"</span>, <span class="string">"/var"</span>)</span>;</span><br><span class="line"> symlink<span class="params">(<span class="string">"/ram/tmp"</span>, <span class="string">"/var/tmp"</span>)</span>;</span><br><span class="line"> symlink<span class="params">(<span class="string">"/ram/tmp"</span>, <span class="string">"/tmp"</span>)</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>调试通道使用 SCI3,故 bspInit 函数加入:</p>
<figure class="highlight dns"><table><tr><td class="code"><pre><span class="line">sciInit()<span class="comment">;</span></span><br></pre></td></tr></table></figure>
<p>同时 hz 修改为 1000:</p>
<figure class="highlight lisp"><table><tr><td class="code"><pre><span class="line">API_KernelStartParam<span class="list">(<span class="string">"kdlog=no kderror=yes kfpu=no heapchk=yes hz=1000 hhz=1000"</span>)</span><span class="comment">;</span></span><br></pre></td></tr></table></figure>
<h3 id="bspLib-c_关键内容">bspLib.c 关键内容</h3><p>中断初始化:</p>
<figure class="highlight gradle"><table><tr><td class="code"><pre><span class="line"><span class="keyword">VOID</span> bspIntInit (<span class="keyword">VOID</span>)</span><br><span class="line">{</span><br><span class="line"> vimInit();</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>中断处理(暂时只支持定时器中断):<br><figure class="highlight openscad"><table><tr><td class="code"><pre><span class="line">VOID bspIntHandle <span class="params">(VOID)</span></span><br><span class="line">{</span><br><span class="line"> REGISTER UINT32 uiVector = <span class="number">2</span>;</span><br><span class="line"></span><br><span class="line"> archIntHandle<span class="params">(<span class="params">(ULONG)</span>uiVector, LW_FALSE)</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>开关中断:</p>
<figure class="highlight openscad"><table><tr><td class="code"><pre><span class="line">VOID bspIntVectorEnable <span class="params">(ULONG ulVector)</span></span><br><span class="line">{</span><br><span class="line"> vimChannelMap<span class="params">(ulVector, ulVector, archIntEntry)</span>;</span><br><span class="line"> vimEnableInterrupt<span class="params">(ulVector, SYS_IRQ)</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">VOID bspIntVectorDisable <span class="params">(ULONG ulVector)</span></span><br><span class="line">{</span><br><span class="line"> vimDisableInterrupt<span class="params">(ulVector)</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>处理器特性:<br><figure class="highlight objectivec"><table><tr><td class="code"><pre><span class="line">ULONG bspInfoHwcap (VOID)</span><br><span class="line">{</span><br><span class="line"> <span class="keyword">return</span> (HW<span class="built_in">CAP_VFP</span> | HW<span class="built_in">CAP_VFPv3</span> | HW<span class="built_in">CAP_VFPv3D16</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>调试信息输出:<br><figure class="highlight aspectj"><table><tr><td class="code"><pre><span class="line"><span class="function">VOID <span class="title">bspDebugMsg</span> <span class="params">(CPCHAR pcMsg)</span></span><br><span class="line"></span>{</span><br><span class="line"> <span class="keyword">if</span> (!pcMsg) { <span class="comment">/* 指针为空 */</span></span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">while</span> (*pcMsg != <span class="string">'\0'</span>) { <span class="comment">/* 发送字符串 */</span></span><br><span class="line"> sciSendByte(sciREG3, *pcMsg);</span><br><span class="line"> pcMsg++;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>定时器相关函数:<br><figure class="highlight openscad"><table><tr><td class="code"><pre><span class="line">static irqreturn_t __tickTimerIsr <span class="params">(VOID)</span></span><br><span class="line">{</span><br><span class="line"> portRTI_INTFLAG_REG = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"> API_KernelTicksContext<span class="params">()</span>; <span class="comment">/* 保存被时钟中断的线程控制块 */</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">#</span><span class="keyword">if</span> TICK_IN_THREAD > <span class="number">0</span></span><br><span class="line"> API_ThreadResume<span class="params">(htKernelTicks)</span>;</span><br><span class="line"><span class="built_in">#</span><span class="keyword">else</span></span><br><span class="line"> API_KernelTicks<span class="params">()</span>; <span class="comment">/* 内核 TICKS 通知 */</span></span><br><span class="line"> API_TimerHTicks<span class="params">()</span>; <span class="comment">/* 高速 TIMER TICKS 通知 */</span></span><br><span class="line"><span class="built_in">#</span>endif <span class="comment">/* TICK_IN_THREAD > 0 */</span></span><br><span class="line"> </span><br><span class="line"> return <span class="params">(LW_IRQ_HANDLED)</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">static void prvSetupTimerInterrupt<span class="params">(void)</span></span><br><span class="line">{</span><br><span class="line"> <span class="comment">/* Disable timer 0. */</span></span><br><span class="line"> portRTI_GCTRL_REG &= <span class="number">0</span>xFFFFFFFEUL;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/* Use the internal counter. */</span></span><br><span class="line"> portRTI_TBCTRL_REG = <span class="number">0</span>x00000000U;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/* COMPSEL0 will use the RTIFRC0 counter. */</span></span><br><span class="line"> portRTI_COMPCTRL_REG = <span class="number">0</span>x00000000U;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/* Initialise the counter and the prescale counter registers. */</span></span><br><span class="line"> portRTI_CNT0_UC0_REG = <span class="number">0</span>x00000000U;</span><br><span class="line"> portRTI_CNT0_FRC0_REG = <span class="number">0</span>x00000000U;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/* Set Prescalar for RTI clock. */</span></span><br><span class="line"> portRTI_CNT0_CPUC0_REG = <span class="number">0</span>x00000001U;</span><br><span class="line"> portRTI_CNT0_COMP0_REG = <span class="params">( configCPU_CLOCK_HZ / <span class="number">2</span> )</span> / LW_TICK_HZ;</span><br><span class="line"> portRTI_CNT0_UDCP0_REG = <span class="params">( configCPU_CLOCK_HZ / <span class="number">2</span> )</span> / LW_TICK_HZ;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/* Clear interrupts. */</span></span><br><span class="line"> portRTI_INTFLAG_REG = <span class="number">0</span>x0007000FU;</span><br><span class="line"> portRTI_CLEARINTENA_REG = <span class="number">0</span>x00070F0FU;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/* Enable the compare 0 interrupt. */</span></span><br><span class="line"> portRTI_SETINTENA_REG = <span class="number">0</span>x00000001U;</span><br><span class="line"> portRTI_GCTRL_REG |= <span class="number">0</span>x00000001U;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">VOID bspTickInit <span class="params">(VOID)</span></span><br><span class="line">{</span><br><span class="line"><span class="built_in">#</span><span class="keyword">if</span> TICK_IN_THREAD > <span class="number">0</span></span><br><span class="line"> LW_CLASS_THREADATTR threadattr;</span><br><span class="line"><span class="built_in">#</span>endif <span class="comment">/* TICK_IN_THREAD > 0 */</span></span><br><span class="line"> ULONG ulVector = <span class="number">2</span>;</span><br><span class="line"></span><br><span class="line"><span class="built_in">#</span><span class="keyword">if</span> TICK_IN_THREAD > <span class="number">0</span></span><br><span class="line"> API_ThreadAttrBuild<span class="params">(&threadattr, <span class="params">(<span class="number">8</span> * LW_CFG_KB_SIZE)</span>,</span><br><span class="line"> LW_PRIO_T_TICK,</span><br><span class="line"> LW_OPTION_THREAD_STK_CHK |</span><br><span class="line"> LW_OPTION_THREAD_UNSELECT |</span><br><span class="line"> LW_OPTION_OBJECT_GLOBAL |</span><br><span class="line"> LW_OPTION_THREAD_SAFE, LW_NULL)</span>;</span><br><span class="line"></span><br><span class="line"> htKernelTicks = API_ThreadCreate<span class="params">(<span class="string">"t_tick"</span>,</span><br><span class="line"> <span class="params">(PTHREAD_START_ROUTINE)</span>__tickThread,</span><br><span class="line"> &threadattr,</span><br><span class="line"> NULL)</span>;</span><br><span class="line"><span class="built_in">#</span>endif <span class="comment">/* TICK_IN_THREAD > 0 */</span></span><br><span class="line"></span><br><span class="line"> prvSetupTimerInterrupt<span class="params">()</span>;</span><br><span class="line"></span><br><span class="line"> API_InterVectorConnect<span class="params">(ulVector,</span><br><span class="line"> <span class="params">(<span class="literal">PI</span>NT_SVR_ROUTINE)</span>__tickTimerIsr,</span><br><span class="line"> LW_NULL,</span><br><span class="line"> <span class="string">"tick_timer"</span>)</span>;</span><br><span class="line"></span><br><span class="line"> API_InterVectorEnable<span class="params">(ulVector)</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<h2 id="CCS调试">CCS调试</h2><p>新建一CCS工程:<br><img src="/img/Hercules-TMS570LC43x-LaunchPad/Image 11.png" alt="Image 11.png"></p>
<p>新建它的调试配置:</p>
<p>配置程序:<br><img src="/img/Hercules-TMS570LC43x-LaunchPad/Image 12.png" alt="Image 12.png"></p>
<p>配置调试开始函数:<br><img src="/img/Hercules-TMS570LC43x-LaunchPad/Image 13.png" alt="Image 13.png"></p>
<p>配置文件查找路径:<br><img src="/img/Hercules-TMS570LC43x-LaunchPad/Image 14.png" alt="Image 14.png"></p>
<p>最后可以把这个调试配置复制一份,调试时只需要加载符号,但不下载,用于快速重启调试:<br><img src="/img/Hercules-TMS570LC43x-LaunchPad/Image 16.png" alt="Image 16.png"></p>
<p>但需要多选择连接时复位:<br><img src="/img/Hercules-TMS570LC43x-LaunchPad/Image 17.png" alt="Image 17.png"></p>
<h2 id="晒图">晒图</h2><p><img src="/img/Hercules-TMS570LC43x-LaunchPad/Image 19.png" alt="Image 19.png"><br><img src="/img/Hercules-TMS570LC43x-LaunchPad/Image 20.png" alt="Image 20.png"></p>
]]></content>
<summary type="html">
<![CDATA[<p>Hercules TMS570LC43x LaunchPad是TI官方出的TMS570LC43x芯片DEMO板:<br><a href="http://www.ti.com/tool/launchxl2-570lc43" target="_blank" rel="exter]]>
</summary>
<category term="ARMv7-R" scheme="jiaojinxing.github.io/tags/ARMv7-R/"/>
<category term="SylixOS" scheme="jiaojinxing.github.io/tags/SylixOS/"/>
<category term="SylixOS" scheme="jiaojinxing.github.io/categories/SylixOS/"/>
</entry>
<entry>
<title><![CDATA[RealEvo-QtSylixOS 功能介绍]]></title>
<link href="jiaojinxing.github.io/2015/11/04/RealEvo-QtSylixOS-%E5%8A%9F%E8%83%BD%E4%BB%8B%E7%BB%8D/"/>
<id>jiaojinxing.github.io/2015/11/04/RealEvo-QtSylixOS-功能介绍/</id>
<published>2015-11-04T13:27:10.000Z</published>
<updated>2015-12-16T01:40:12.085Z</updated>
<content type="html"><![CDATA[<p>经过长约一年断断续续的开发, RealEvo-QtSylixOS 的功能已经开发完毕, 在这里说说 RealEvo-QtSylixOS 的功能。</p>
<p>RealEvo-QtSylixOS 是北京翼辉信息技术有限公司专门为开发 SylixOS 系统上的 Qt 应用程序而推出的软件。</p>
<p>RealEvo-QtSylixOS 集成了 Qt Creator 的 SylixOS 插件、各种类型处理器上的基于 LGPL协议的 Qt 共享库、支持 Python 的 gdb 调试工具、 Qwt 等。</p>
<p>SylixOS 插件使得 Qt Creator 几乎零配置就可以开发 SylixOS 上的 Qt 应用程序,一键部署 Qt 共享库到 SylixOS 设备使得 Qt 应用程序环境的配置变得异常简单,一键部署、运行、调试、分析 Qt 应用程序极大地提升了开发者的效率。</p>
<p>同时, RealEvo-QtSylixOS 集成了各种类型处理器上的基于 LGPL 协议的 Qt 共享库,既使得开发者免于编译 Qt,将精力集中于开发 Qt 应用程序上,又节省了企业购买 Qt 的成本。</p>
<p>备注: LGPL 允许商业软件通过类库引用( link) 方式使用 LGPL 类库而不需要开源商业软件的代码。这使得采用 LGPL 协议的开源代码可以被商业软件作为类库引用并发布和销售。</p>
]]></content>
<summary type="html">
<![CDATA[<p>经过长约一年断断续续的开发, RealEvo-QtSylixOS 的功能已经开发完毕, 在这里说说 RealEvo-QtSylixOS 的功能。</p>
<p>RealEvo-QtSylixOS 是北京翼辉信息技术有限公司专门为开发 SylixOS 系统上的 Qt 应用程序]]>
</summary>
<category term="SylixOS" scheme="jiaojinxing.github.io/tags/SylixOS/"/>
<category term="SylixOS" scheme="jiaojinxing.github.io/categories/SylixOS/"/>
</entry>
<entry>
<title><![CDATA[MIPS 学习]]></title>
<link href="jiaojinxing.github.io/2015/09/21/MIPS-%E5%AD%A6%E4%B9%A0/"/>
<id>jiaojinxing.github.io/2015/09/21/MIPS-学习/</id>
<published>2015-09-21T12:00:58.000Z</published>
<updated>2015-09-22T06:06:46.051Z</updated>
<content type="html"><![CDATA[<h2 id="MIPS指令">MIPS指令</h2><h3 id="MIPS的指令特点">MIPS的指令特点</h3><ol>
<li><p>所有指令都是32位编码;</p>
</li>
<li><p>有些指令有26位供目标地址编码;有些则只有16位。因此要想加载任何一个32位值,就得用两个加载指令。</p>
</li>
<li><p>所有的动作原理上要求必须在1个时钟周期内完成,一个动作一个阶段;</p>
</li>
<li><p>有32个通用寄存器,每个寄存器32位(对32位机)或64位(对64位机);</p>
</li>
<li><p>本身没有任何帮助运算判断的标志寄存器,要实现相应的功能时,是通过测试两个寄存器是否相等来完成的;</p>
</li>
<li><p>所有的运算都是基于32位的,没有对字节和对半字的运算(MIPS里,字定义为32位,半字定义为16位);</p>
</li>
<li><p>没有单独的栈指令,所有对栈的操作都是统一的内存访问方式。因为push和pop指令实际上是一个复合操作,包含对内存的写入和对栈指针的移动;</p>
</li>
<li><p>由于MIPS固定指令长度,所以造成其编译后的二进制文件和内存占用空间比x86的要大,(x86平均指令长度只有3个字节多一点,而MIPS是4个字节);</p>
</li>
<li><p>寻址方式:只有一种内存寻址方式。就是基地址加一个16位的地址偏移;</p>
</li>
<li><p>内存中的数据访问必须严格对齐(至少4字节对齐);</p>
</li>
<li><p>跳转指令只有26位目标地址,再加上2位的对齐位,可寻址28位的空间,即256M。意思即是说,在一个C程序内,goto语句只能跳转到它之前的128M和之后的128M这个地址空间之内;</p>
</li>
<li><p>条件分支指令只有16位跳转地址,加上2位的对齐位,共18位寻址空间,即256K。意思即是说,在一个C程序内,if语句只能跳转到它之前的128K和之后的128K这个地址空间之内;</p>
</li>
<li><p>MIPS默认不把子函数的返回地址(就是调用函数的受害指令地址)存放到栈中,而是存放到R31寄存器中;这对那些叶子函数有利。如果遇到嵌套的函数的话,有另外的机制处理;</p>
</li>
<li><p>流水线效应。由于采用了高度的流水线,结果产生了一些对程序员来说可见的效应,需要注意。最重要的两个效应就是分支延迟效应和载入延迟效应。</p>
</li>
</ol>
<h3 id="五级流水线">五级流水线</h3><p>每条指令都包含五个执行阶段。</p>
<ol>
<li>第一阶段:从指令缓冲区中取指令。占一个时钟周期;</li>
<li>第二阶段:从指令中的源寄存器域(可能有两个)的值(为一个数字,指定\$0~\$31中的某一个)所代表的寄存器中读出数据。占半个时钟周期;</li>
<li>第三阶段:在一个时钟周期内做一次算术或逻辑运算。占一个时钟周期;</li>
<li>第四阶段:指令从数据缓冲中读取内存变量的阶段。从平均来讲,大约有3/4的指令在这个阶段没做什么事情,但它是指令有序性的保证。占一个时钟周期;</li>
<li>第五阶段:存储计算结果到缓冲或内存的阶段。占半个时钟周期;</li>
</ol>
<p>所以一条指令要占用四个时钟周期。</p>
<h3 id="分支延迟槽">分支延迟槽</h3><ul>
<li>任何一个分支跳转语句后面的那条语句叫做分支延迟槽。实际上在程序执行到分支语句时,当它刚把要跳转到的地址填充好(到代码计数器里),还没完成本条指令,分支语句后面的那条指令就执行了。这是因为流水线效应,几条指令同时在执行,只是处于不同的阶段。分支延迟槽常用被利用起来完成一些参数初始化等相关工作,而不是被浪费了。</li>
</ul>
<h3 id="载入延迟">载入延迟</h3><ul>
<li>载入延迟是这样的,当执行一条从内存中载入数据的指令时,是先载入到高速缓冲中,然后再取到寄存器中,这个过程相对来说是比较慢的。在这个过程完成之前,可能已经有几条在流水线上的指令被执行了。这几条在载入数据指令后被执行的指令就被称作载入延迟槽。现在就有一个问题,如果后面这几条指令要用到载入数据指令所载入的那个数据怎么办?一个通用的办法是,把内部锁加在数据载入过程上,这样,当后面的指令要用这个数据时,就只有先停止运行(在ALU阶段),等这条载入数据指令完成了后再开始运行。</li>
</ul>
<h2 id="MIPS的指令格式">MIPS的指令格式</h2><p>MIPS的所有指令都是32位的,指令格式简单。不像x86那样,x86的指令长度不是固定的,以80386为例, 其指令长度可从1字节(例如PUSH)到17字节,这样的好处代码密度高,所以MIPS的二进制文件要比x86的大大约20%~30%。而定长指令和格式简单的好处是易于译码和更符合流水线操作,由于指令中指定的寄存器位置是固定的,使得译码过程和读指令的过程可以同时进行,即固定字段译码。</p>
<p>为了让指令的格式刚好合适,于是设计者做了一个折衷:所有指令定长,但是不同的指令有不同的格式。MIPS指令有三种格式:R格式,I格式,J格式。每种格式都由若干字段(filed)组成,图示如下:</p>
<h3 id="I型指令">I型指令</h3><table>
<thead>
<tr>
<th>6</th>
<th style="text-align:left">5</th>
<th style="text-align:left">5</th>
<th style="text-align:left">16</th>
</tr>
</thead>
<tbody>
<tr>
<td>op</td>
<td style="text-align:left">rs</td>
<td style="text-align:left">rt</td>
<td style="text-align:left">立即数操作</td>
</tr>
</tbody>
</table>
<ol>
<li>加载/存储字节,半字,字,双字</li>
<li>条件分支,跳转,跳转并链接寄存器</li>
</ol>
<h3 id="R型指令">R型指令</h3><table>
<thead>
<tr>
<th>6</th>
<th style="text-align:left">5</th>
<th style="text-align:left">5</th>
<th style="text-align:left">5</th>
<th style="text-align:left">5</th>
<th style="text-align:left">6</th>
</tr>
</thead>
<tbody>
<tr>
<td>op</td>
<td style="text-align:left">rs</td>
<td style="text-align:left">rt</td>
<td style="text-align:left">rd</td>
<td style="text-align:left">shamt</td>
<td style="text-align:left">funct </td>
</tr>
</tbody>
</table>
<ol>
<li>寄存器-寄存器ALU操作</li>
<li>读写专用寄存器</li>
</ol>
<h3 id="J型指令">J型指令</h3><table>
<thead>
<tr>
<th>6</th>
<th style="text-align:left">26</th>
</tr>
</thead>
<tbody>
<tr>
<td>op</td>
<td style="text-align:left">跳转地址</td>
</tr>
</tbody>
</table>
<ol>
<li>跳转,跳转并链接</li>
<li>陷阱和从异常中返回</li>
</ol>
<h3 id="各字段含义">各字段含义</h3><ol>
<li>op: 指令基本操作,称为操作码。</li>
<li>rs: 第一个源操作数寄存器。</li>
<li>rt: 第二个源操作数寄存器。</li>
<li>rd: 存放操作结果的目的操作数寄存器。</li>
<li>shamt: 位移量</li>
<li>funct: 函数,这个字段选择op操作的某个特定变体。 </li>
</ol>
<h3 id="跳转范围">跳转范围</h3><p>J指令的地址字段为26位,用于跳转目标。指令在内存中以4字节对齐,最低两个有效位不需要存储。在MIPS中,每个地址的最低两位指定了字的一个字 节,cache映射的下标是不使用这两位的,这样能表示28位的字节编址,允许的地址空间为256M。PC是32位的,那其它4位从何而来呢?MIPS的跳转指令只替换PC的低28位,而高4位保留原值。因此,加载和链接程序必须避免跨越256MB,在256M的段内,分支跳转地址当作一个绝对地址,和PC无关。</p>
<p>如果超过256M(段外跳转)就要用跳转寄存器指令了。</p>
<p>同样,条件分支指令中的16位立即数如果不够用,可以使用PC相对寻址,即用分支指令中的分支地址与(PC+4)的和做分支目标。由于一般的循环和if语句都小于2^16个字(2的16次方),这样的方法是很理想的。</p>
<h3 id="31条MIPS指令">31条MIPS指令</h3><p><img src="/img/MIPS-学习/mips指令.png" alt="mips指令.png"></p>
<h2 id="MIPS的通用寄存器">MIPS的通用寄存器</h2><p>MIPS CPU有32个通用寄存器(GPR),\$0到\$31。</p>
<p>寄存器分配在编译优化中是最重要的优化之一(也许是做重要的)。现在的寄存器分配算法都是基于图着色的技术。其基本思想是构造一个图,用以代表分配寄存器的各个方案,然后用此图来分配寄存器。粗略说来就是使用有限的颜色使图中相临的节点着以不同的颜色,图着色问题是个图大小的指数函数,有些启发式算法产生近乎线形时间运行的分配。全局分配中如果有16个通用寄存器用于整型变量,同时另有额外的寄存器用于浮点数,那么图着色会很好的工作。在寄存器数较少时候图着色并不能很好的工作。</p>
<p>问: 既然不能少于16个,那为什么不用64个呢?</p>
<p>答: 使用64个或更多寄存器不但需要更大的指令空间来对寄存器编码,还会增加上下文切换的负担。除了那些很大非常复杂的函数,32个寄存器就已足够保存经常使用的数据。使用更多的寄存器并不必要,同时计算机设计有个原则叫“越小越快”,但是也不是说使用31个寄存器会比32个性能更好,32个通用寄存器是流行的做法。</p>
<p>\$0: 即\$zero,该寄存器总是返回零,为0这个有用常数提供了一个简洁的编码形式。MIPS编译器使用slt,beq,bne等指令和由寄存器\$0获得的0来产生所有的比较条件:相等,不等,小于,小于等于,大于,大于等于。还可以用add指令创建move伪指令,即</p>
<figure class="highlight mel"><table><tr><td class="code"><pre><span class="line"><span class="keyword">move</span> <span class="variable">$t0</span>,<span class="variable">$t1</span></span><br></pre></td></tr></table></figure>
<p>实际为<br><figure class="highlight dockerfile"><table><tr><td class="code"><pre><span class="line"><span class="built_in">add</span> <span class="bash"><span class="variable">$t0</span>,<span class="variable">$0</span>,<span class="variable">$t1</span></span></span><br></pre></td></tr></table></figure></p>
<p>使用伪指令可以简化任务,使汇编程序提供了比硬件更丰富的指令集。</p>
<p>\$1: 即\$at,该寄存器为汇编保留,刚才说到使用伪指令可以简化任务,但是代价就是要为汇编程序保留一个寄存器,就是\$at。由于I型指令的立即数字段只有16位,在加载大常数时,编译器或汇编程序需要把大常数拆开,然后重新组合到寄存器里。<br>比如加载一个32位立即数需要lui(装入高位立即数)和addi两条指令。像MIPS程序拆散和重装大常数由汇编程序来完成,汇编程序必需一个临时寄存器来重组大常数,这也是为汇编保留\$at的原因之一。如果你要显示的使用这个寄存器(比如在异常处理程序中保存和恢复寄存器),有一个汇编directive可被用来禁止汇编器在directive之后再使用at寄存器(但是汇编的一些宏指令将因此不能再可用)。</p>
<p>\$2..\$3: (\$v0-\$v1)用于子程序的非浮点结果或返回值,对于子程序如何传递参数及如何返回,MIPS范围有一套约定,堆栈中少数几个位置处的内容装入CPU寄存器,其相应内存位置保留未做定义,当这两个寄存器不够存放返回值时,编译器通过内存来完成。</p>
<p>\$4..\$7: (\$a0-\$a3)用来传递前四个参数给子程序,不够的用堆栈。a0-a3和v0-v1以及ra一起来支持子程序/过程调用,分别用以传递参数,返回结果和存放返回地址。当需要使用更多的寄存器时,就需要堆栈了,MIPS编译器总是为参数在堆栈中留有空间以防有参数需要存储。</p>
<p>\$8..\$15: (\$t0-\$t7)临时寄存器,子程序可以使用它们而不用保留。</p>
<p>\$16..\$23: (\$s0-\$s7)保存寄存器,在过程调用过程中需要保留(被调用者保存和恢复,还包括\$fp和\$ra),MIPS提供了临时寄存器和保存寄存器,这样就减少了寄存器溢出(spilling,即将不常用的变量放到存储器的过程),编译器在编译一个叶(leaf)过程(不调用其它过程的过程)的时候,总是在临时寄存器分配完了才使用需要保存的寄存器。</p>
<p>\$24..\$25: (\$t8-\$t9)同(\$t0-\$t7)。</p>
<p>\$26..\$27: (\$k0,\$k1)为操作系统/异常处理保留,至少要预留一个。 异常(或中断)是一种不需要在程序中显示调用的过程。MIPS有个叫异常程序计数器(exception program counter,EPC)的寄存器,属于CP0寄存器,用于保存造成异常的那条指令的地址。查看控制寄存器的唯一方法是把它复制到通用寄存器里,指令mfc0(move from system control)可以将EPC中的地址复制到某个通用寄存器中,通过跳转语句(jr),程序可以返回到造成异常的那条指令处继续执行。仔细分析一下会发现个有意思的事情:</p>
<p>为了查看控制寄存器EPC的值并跳转到造成异常的那条指令(使用jr),必须把EPC的值到某个通用寄存器里,这样的话,程序返回到中断处时就无法将所有的寄存器恢复原值。如果先恢复所有的寄存器,那么从EPC复制过来的值就会丢失,jr就无法返回中断处;如果我们只是恢复除有从EPC复制过来的返回地址外的寄存器,但这意味着程序在异常情况后某个寄存器被无端改变了,这是不行的。为了摆脱这个两难境地,MIPS程序员都必须保留两个寄存器\$k0和\$k1,供操作系统使用。发生异常时,这两个寄存器的值不会被恢复,编译器也不使用k0和k1,异常处理函数可以将返回地址放到这两个中的任何一个,然后使用jr跳转到造成异常的指令处继续执行。</p>
<p>\$28: (\$gp)C语言中有两种存储类型,自动型和静态型,自动变量是一个过程中的局部变量。静态变量是进入和退出一个过程时都是存在的。为了简化静态数据的访问,MIPS软件保留了一个寄存器:全局指针gp(global pointer,\$gp),如果没有全局指针,从静态数据去装入数据需要两条指令:一条有编译器和链接器计算的32位地址常量中的有效位;另一条才真正装入数据。全局指针指向静态数据区中的运行时决定的地址,在存取位于gp值上下32KB范围内的数据时,只需要一条以gp为基指针的指令即可。在编译时,数据须在以gp为基指针的64KB范围内。</p>
<p>\$29: (\$sp)MIPS硬件并不直接支持堆栈,例如,它没有x86的SS,SP,BP寄存器,MIPS虽然定义\$29为栈指针,它还是通用寄存器,只是用于特殊目的而已,你可以把它用于别的目的,但为了使用别人的程序或让别人使用你的程序,还是要遵守这个约定的,但这和硬件没有关系。x86有单独的PUSH和POP指令,而MIPS没有,但这并不影响MIPS使用堆栈。在发生过程调用时,调用者把过程调用过后要用的寄存器压入堆栈,被调用者把返回地址寄存器\$ra和保留寄存器压入堆栈。同时调整堆栈指针,当返回时,从堆栈中恢复寄存器,同时调整堆栈指针。</p>
<p>\$30: (\$fp)GNU MIPS C编译器使用了侦指针(frame pointer),而SGI的C编译器没有使用,而把这个寄存器当作保存寄存器使用(\$s8),这节省了调用和返回开销,但增加了代码生成的复杂性。</p>
<p>\$31: (\$ra)存放返回地址,MIPS 有个jal(jump-and-link,跳转并链接)指令,在跳转到某个地址时,把下一条指令的地址放到\$ra中。用于支持子程序,例如调用程序把参数放到\$a0~\$a3,然后jal X跳到X过程,被调过程完成后把结果放到\$v0,\$v1,然后使用jr \$ra返回。<br>在调用时需要保存的寄存器为\$a0~\$a3,\$s0~\$s7,\$gp,\$sp,\$fp,\$ra。</p>
<h2 id="MIPS的虚拟地址内存映射空间">MIPS的虚拟地址内存映射空间</h2><ol>
<li>0x0000 0000 ~ 0x7fff ffff :kuseg 用户级空间,2GB,要经MMU(TLB)地址翻译。可以控制要不要经过缓冲。</li>
<li>0x8000 0000 ~ 0x9fff ffff :kseg0,这块区域为操作系统内核所占的区域,共512M。使用时,不经过地址翻译,将最高位去掉就线性映射到内存的低512M(不足的就裁剪掉顶部)。但要经过缓冲区过渡。</li>
<li>0xa000 0000 ~ 0xbfff ffff :kseg1,这块区域为系统初始化所占区域,共512M。使用时,不经过地址翻译,也不经过缓冲区。将最高3位去掉就线性映射到内存的低512M(不足的就裁剪掉顶部)。</li>
<li>0xc000 0000 ~ 0xffff ffff :kseg2,这块区域也为内核级区域。要经过地址翻译。可以控制要不要经过缓冲。</li>
</ol>
<p>注意:地址空间的0x0000 0000是不能用的,从0开始的一个或多个页不会被映射。</p>
<h2 id="MIPS的协处理器">MIPS的协处理器</h2><p>在MIPS体系结构中,最多支持4个协处理器(Co-Processor)。其中,协处理器CP0是体系结构中必须实现的。它起到控制CPU的作用。MMU、异常处理、乘除法等功能,都依赖于协处理器CP0来实现。它是MIPS的精髓之一,也是打开MIPS特权级模式的大门。</p>
<h3 id="CP0">CP0</h3><p>CP0:这是MIPS芯片的配置单元。必不可少,虽然叫做协处理器,但是通常都是做在一块芯片上。绝大部分MIPS功能的配置,缓冲的控制,异常/中断的控制,内存管理的控制都在这里面。所以是一个完整的系统所必不可少的。</p>
<p>MIPS的CP0包含32个寄存器。关于它们的资料可以参照MIPS官方的资料MIPS32(R) Architecture For Programmers Volume III: The MIPS32(R) Privileged Resource Architecture的Chap7和Chap8。本文中,仅讨论常见的一些寄存器。</p>
<ol>
<li><p>Register 0: Index,作为MMU的索引用。将来讨论MMU和TLB时会详解之。</p>
</li>
<li><p>Register 2, EntryLo0,访问TLB Entry偶数页中的地址低32Bit用。同上,在MMU和TLB的相关章节中详解。</p>
</li>
<li><p>Register 3, EntryLo1,访问TLB Entry奇数页中的地址低32Bit用。</p>
</li>
<li><p>Register 4, Context,用以加速TLB Miss异常的处理。</p>
</li>
<li><p>Register 5, PageMask,用以在MMU中分配可变大小的内存页。</p>
</li>
<li><p>Register 8, BadVAddr,在系统捕获到TLB Miss或Address Error这两种Exception时,发生错误的虚拟地址会储存在该寄存器中。对于引发Exception的Bug的定位来说,这个寄存器非常重要。</p>
</li>
<li><p>Register 9, Count,这个寄存器是R4000以后的MIPS系统引入的。它是一个计数器,计数频率是系统主频的1/2。BCM1125/1250,RMI XLR系列以及Octeon的Cavium处理器均支持该寄存器。对于操作系统来说,可以通过读取该寄存器的值来获取tick的时基。在系统性能测试中,利用该寄存器也可以实现打点计数。</p>
</li>
<li><p>Register 10,EntryHi,这个寄存器同EntryLo0/1一样,用于MMU中。以后会详述。</p>
</li>
<li><p>Register 11,Compare,配合Count使用。当Compare和Count的值相等的时候,会触发一个硬件中断(Hardware Interrupt),并且总是使用Cause寄存器的IP7位。</p>
</li>
<li><p>Register 12,Status,用于处理器状态的控制。</p>
</li>
<li><p>Register 13,Cause,这个寄存器体现了处理器异常发生的原因。</p>
</li>
<li><p>Register 14,EPC,这个寄存器存放异常发生时,系统正在执行的指令的地址。</p>
</li>
<li><p>Register 15,PRID,这个寄存器是只读的,标识处理器的版本信息。向其中写入无意义。</p>
</li>
<li><p>Register 18/19,WatchLo/WatchHi,这对寄存器用于设置硬件数据断点(Hardware Data Breakpoint)。该断点一旦设定,当CPU存取这个地址时,系统就会发生一个异常。这个功能广泛应用于调试定位内存写坏的错误。</p>
</li>
<li><p>Register 28/29,TagLo和TagHi,用于高速缓存(Cache)管理。</p>
</li>
</ol>
<p>下面,我们来详解CP0中常用的几个寄存器,它们是:BadVAddr,Count/Compare,Status/Cause,EPC,WatchLo/WatchHi。</p>
<ul>
<li><p>BadVAddr: 错误的虚拟地址。实际上,这个寄存器仅限于出现TLB Miss和ADE (Address Error)两种异常的时候,才能用到。发生错误的虚拟地址会放在这个寄存器里。<br>一般地,在设定TLB时,通常将0地址附近的一块,设定为无映射区域。这样,一旦编程时不慎访问了空指针(0地址),或是空指针加上一定的偏移量,那么,系统就会抛出一个TLB Miss Exception。在这种情况下,发生错误的地址会被记录在BadVAddr寄存器中。一般地,这个地址是一个非常接近于0的地址。往往地,通过BadVAddr在寄存器中的值,和相关数据结构的分析,就可以找出对应的语句。<br>另外,对于ADE异常,异常地址也会被保存在BadVAddr中。一般地,操作系统会自行接管这个地址,分两次读取/写入这个地址处的数据,而不会发生Core Dump的情况。但是,如果这个地址既属于非对齐地址,又属于TLB Miss,那么,系统还是会抛出一个Core Dump的。正常地,操作系统应当正确处理这个异常,如果在Exception Handler中发现地址在TLB中未映射,还是应当抛出ADE异常,而不是TLB Miss。</p>
</li>
<li><p>Count/Compare: 这两个寄存器是CP0中的一对欢喜冤家。Count是一个计数器,每两个系统时钟周期,Count会增加1,而当它的值和Compare相等时,会发生一个硬件中断(Hardware Interrupt)。这个特性经常用来为操作系统提供一个可靠的tick时脉。</p>
</li>
<li><p>Status: 这个寄存器标识了处理器的状态。其中,中断控制的8个IM(Interrupt Mask)位和设定处理器大小端的RE(Reverse Endianess)位。8个IM位,分别可以控制8个硬件中断源。它们将在讲述‘硬件中断’时详解。RE位很有趣,设定这个Bit可以让CPU在大端(Big Endian)和小端(Little Endian)之间切换。默认情况下,MIPS处理器是大端的,和网络序相同。但是,为了能在MIPS上运行类似Windows NT的服务器操作系统,设定这个Bit可以令处理器工作在Little Endian模式下。</p>
</li>
<li><p>EPC: 这个寄存器的作用很简单,就是保存异常发生时的指令地址。从这个地方可以找到异常发生的指令,再结合BadVAddr, sp, ra等寄存器,就可以推导出异常时的程序调用关系,从而定位问题的根因。一旦异常发生时EPC的内容丢失,那么对异常的定位将是一件非常困难的事情。</p>
</li>
<li><p>WatchLo/WatchHi: 这一对寄存器可以用来设定“内存硬件断点”,也就是对指定点的内存进行监测。当访问的内存地址和这两个寄存器中地址一致时,会发生一个异常。为了适应64Bit的一些扩展功能,某些MIPS处理器又对这两个寄存器的功能做了一些修改,与MIPS体系结构的定义已经有了差别,如RMI的多核处理器等。</p>
</li>
<li><p>Cause: 在处理器异常发生时,这个寄存器标识出了异常的原因。其中,最重要的是从Bit2到Bit6,5个Bit的Excetion Code位。它们标识出了引起异常的原因。</p>
</li>
</ul>
<p>由于协处理器CP0的访问,需要使用特别的指令。这些指令属于“特权级指令”,只有在内核态(Kernel Mode)下才能执行。如果在用户态下,会引起一个异常(Exception)。 </p>
<h3 id="CP0_操作指令">CP0 操作指令</h3><p>对CP0的主要操作有以下的指令:<br><figure class="highlight dos"><table><tr><td class="code"><pre><span class="line">mfc0 rt, <span class="built_in">rd</span> 将CP0中的<span class="built_in">rd</span>寄存器内容传输到rt通用寄存器; </span><br><span class="line">mtc0 rt, <span class="built_in">rd</span> 将rt通用寄存器中内容传输到CP0中寄存器<span class="built_in">rd</span>; </span><br><span class="line">mfhi/mflo rt 将CP0的hi/lo寄存器内容传输到rt通用寄存器中; </span><br><span class="line">mthi/mtlo rt 将rt通用寄存器内容传输到CP0的hi/lo寄存器中;</span><br></pre></td></tr></table></figure></p>
<h3 id="CP0_冒险">CP0 冒险</h3><p>当MIPS体系结构演进到MIPS IV的64位架构后,新增了两条指令dmfc0和dmtc0,向CP0的寄存器中读/写一个64bit的数据。<br>前面提到,MIPS体系结构是一个无互锁,高度流水的五级pipeline架构,这就意味着,前一条指令如果尚未执行完,后一条指令有可能已经进入了取指令/译码阶段。这样,就有可能发生所谓的CP0冒险(CP0 Hazard)现象。简单地说,就是mfc和mtc指令的执行速度是比较慢的,因此,开始执行完下一条指令时,有可能CP0寄存器的值尚未最后传输到指定的目标通用寄存器中。此时,如果读取该通用寄存器,有可能并未得到正确的值。这就是所谓的CP0冒险现象。 </p>
<p>为了避免CP0冒险,我们在编程时需要在CP0操作指令的后面加上一条与前一条指令的目的通用寄存器无关的指令,也就是所谓的延迟槽(delay slot)。如果对性能不敏感,可以考虑CP0操作后插入足够多的nop指令填充延迟槽。 </p>
<p>例如,经常在异常处理例程(exception handler)中出现的内容:</p>
<figure class="highlight armasm"><table><tr><td class="code"><pre><span class="line"><span class="label">mfc0</span> k0, $cause </span><br><span class="line"><span class="keyword">nop </span><span class="comment">/* mfc0指令执行速度慢,在延迟槽中加一个空操作 */</span> </span><br><span class="line"><span class="keyword">mov </span>t0, k0 <span class="comment">/* 将cause寄存器内容放到t0,进行下一步操作 */</span></span><br></pre></td></tr></table></figure>
<p>另外一种软件方式就是插入一条ehb指令,比如:</p>
<figure class="highlight nginx"><table><tr><td class="code"><pre><span class="line"><span class="title">mtc0</span> t0, SR</span><br><span class="line">ehb</span><br></pre></td></tr></table></figure>
<p>其中ehb为exception hazard barrier,这个主要有MIPS的pipe lines引起,大致可以理解为由于MIPS采用的流水线(pipe lines)结构,即使在异常处理代码中(这里由于改变了状态寄存器情况类似),由于流水线的作用,异常处理结束时,其下一条(可能超过一条,依赖流水线的设计)仍然被预取执行,这样由于CPU的特权级别发生了改变,但被流水线预取的指令并不知道这些,因而导致严重的安全性问题。为了避免这种情况发生,MIPS专门使用了ehb指令。类似的指令还包括eret,即从异常(原子的,atomically)返回。</p>
<p>另外,SSNOP指令也值得注意,它可以自动知道需要停顿的周期数。</p>
<h2 id="MIPS的异常">MIPS的异常</h2><h3 id="精确异常">精确异常</h3><p>精确异常的概念:在运行流程中没有任何多余效应的异常。即当异常发生时,在受害指令之前的指令被完全执行,而受害指令及后面的指令还没开始执行(注:说受害指令及后面的指令还没做任何事情是不对的,实际上受害指令是处于其指令周期的第三阶段刚完成,即ALU阶段刚完成)。精确异常有助于保证软件设计上不受硬件实现的影响。</p>
<p>CP0中的EPC寄存器用于指向异常发生时指令跳转前的执行位置,一般是受害指令地址。当异常时,是返回这个地址继续执行。但如果受害指令在分支延迟槽中,则会硬件自动处理使EPC往回指一条指令,即分支指令。在重新执行分支指令时,分支延迟槽中的指令会被再执行一次。</p>
<p>精确异常的实现对流水线的流畅性是有一定的影响的,如果异常太多,系统执行效率就会受到影响。</p>
<h3 id="异常类型">异常类型</h3><p>异常又分常规异常和中断两类。常规异常一般为软件的异常,而中断一般为硬件异常,中断可以是芯片内部,也可以是芯片外部触发产生。</p>
<p>MIPS系统把重启看作一个不可回归的异常来处理。</p>
<ol>
<li>冷启动:CPU硬件完全被重新配置,软件重新加载;</li>
<li>热启动:软件完全重新初始化;</li>
</ol>
<p>其中,Exception 0-5, 8-11, 13, 23这几个异常类型较为常见。</p>
<ol>
<li><p>Exception 0:Interrupt,外部中断。它是唯一一个异步发生的异常。之所以说中断是异步发生的,是因为相对于其他异常来说,从时序上看,中断的发生是不可预料的,无法确定中断的发生是在流水线的哪一个阶段。MIPS的五级流水线设计如下:<br>IF, RD, ALU, MEM, WB。MIPS处理器的中断控制部分有这样的设计:在中断发生时,如果该指令已经完成了MEM阶段的操作,则保证该指令执行完毕。反之,则丢弃流水线对这条指令的工作。除NMI外,所有的内部或外部硬件中断(Hardware Interrupt)均共用这一个异常向量(Exception Vector)。前面提到的CP0中的Counter/Compare这一对计数寄存器,当Counter计数值和Compare门限值相等时,即触发一个硬件中断。</p>
</li>
<li><p>Exception 1:TLB Modified,内存修改异常。如果一块内存在TLB映射时,其属性设定为Read Only,那么,在试图修改这块内存内容时,处理器就会进入这个异常。显然,这个异常是在Memory阶段发生的。但是,按“精确异常”的原则,在异常发生时,ALU阶段的操作均无效,也就是说,向内存地址中的写入操作,实际上是不会被真正执行的。这一判断原则,也适用于后面的内存读写相关的异常,包括TLB Miss/Address Error/Watch等。</p>
</li>
<li><p>Exception 2/3:TLB Miss Load/Write,如果试图访问没有在MMU的TLB中映射的内存地址,会触发这个异常。在支持虚拟内存的操作系统中,这会触发内存的页面倒换,系统的Exception Handler会将所需要的内存页从虚拟内存中调入物理内存,并更新相应的TLB表项。</p>
</li>
<li><p>Exception 4/5:Address Error Load/Write,如果试图访问一个非对齐的地址,例如lw/sw指令的地址非4字节对齐,或lh/sh的地址非2字节对齐,就会触发这个异常。一般地,操作系统在Exception Handler中对这个异常的处理,是分开两次读取/写入这个地址。虽然一般的操作系统内核都处理了这个异常,最后能够完成期待的操作,但是由于会引起用户态到内核态的切换,以及异常的退出,当这样非对齐操作较多时会严重影响程序的运行效率。因此,编译器在定义局部和全局变量时,都会自动考虑到对齐的情况,而程序员在设计数据结构时,则需要对对齐做特别的斟酌。</p>
</li>
<li><p>Exception 6/7:Instruction/Data Bus Error,一般地原因是Cache尚未初始化的时候访问了Cached的内存空间所致。因此,要注意在系统上电后,Cache初始化之前,只访问Uncached的地址空间,也就是0xA0000000-0xBFFFFFFF这一段。默认地,上电初始化的入口点0xBFC00000就位于这一段。(某些MIPS实现中可以通过外部硬线连接修改入口点地址,但为了不引发无法预料的问题,不要将入口点地址修改为Uncached段以外的地址)</p>
</li>
<li><p>Exception 8:Syscall,系统调用的正规入口,也就是在用户模式下进入内核态的正规方式。我们可以类比x86下Linux的系统调用0x80来理解它。它是由一条专用指令syscall触发的。</p>
</li>
<li><p>Exception 9:Break Point,绝对断点指令。和syscall指令类似,它也是由专用指令break触发的。它指示了系统的一些异常情况,编程人员可以在某些不应当出现的异常分支里面加入这个指令,便于及早发现问题和调试。我们可以用高级语言中的assert机制来类比理解它。最常见的Break异常的子类型为0x07,它是编译器在编译除法运算时自动加入的。如果除数为0则执行一条break 0x07指令。这样,当出现被0除的情况时,系统就会抛出一个异常,并执行Coredump,以便于程序员定位除0错误的根因。</p>
</li>
<li><p>Exception 10:RI,执行了没有定义的指令,系统就会发生这个异常。</p>
</li>
<li><p>Exception 11,Co-Processor Unaviliable,试图访问的协处理器不存在。比如,在没有实现CP2的处理器上执行对CP2的操作,就会触发这个异常。</p>
</li>
<li><p>Exception 12,Overflow,算术溢出。会引起这个异常的指令,仅限于加减法中的带符号运算,如add/addi这样的指令。因此,一般地,编译器总是将加减法运算编译为addiu这样的无符号指令。由于MIPS处理异常需要一定的开销,这样可以避免浪费。</p>
</li>
<li><p>Exception 13,Trap,条件断点指令。它由trap系列指令引发。与Break指令不同的是,只有满足断点指令中的条件,才会触发这个异常。我们可以类比x86下的int 3断点异常来理解它。</p>
</li>
<li><p>Exception 14,VCEI,(不明白!谁知道是干嘛使的?)<br>Exceotion 15,Float Point Exception,浮点协处理器1的异常。它由CP1自行定义,与CP1的具体实现相关。其实就是专门为CP1保留的异常入口。</p>
</li>
<li><p>Exception 16,协处理器2的异常,和前一个异常一样,是和CP2的具体实现相关的。</p>
</li>
<li><p>Exception 23,Watch异常。前面讲到Watch寄存器可以监控一段内存,当访问/修改这段内存时,就会触发这个异常。在异常处理例程中,通过异常栈可以反推出是什么地方对这段内存进行了读/写操作。这个异常是用来定位内存意外写坏问题的一柄利器。</p>
</li>
</ol>
<h3 id="异常处理过程-硬件部分">异常处理过程-硬件部分</h3><p>异常发生时,跳转前最后被执行的指令是其MEM阶段刚好被执行完的那条指令。受害指令是其ALU阶段刚好执行完的那条指令。</p>
<p>异常发生时,会跳到异常向量入口中去执行。MIPS的异常向量有点特殊,它一般只个2个或几个中断向量入口,一个入口给一般的异常使用,一个入口给 TLB miss异常使用(这样的话,可以省下计算异常类型的时间。在这种机制帮助下,系统只用13个时钟周期就可以把TLB重填好)。</p>
<p>CP0寄存器中有个模式位,SR(BEV),只要设置了,就会把异常入口点转移到非缓冲内存地址空间中(kseg1)。</p>
<p>MIPS对异常的处理的哲学是给异常分配一些类型,然后由软件给它们定义一些优先级,然后由同一个入口进入异常分配程序,在分配程序中根据类型及优先级确定该执行哪个对应的函数。这种机制对两个或几个异常同时出现的情况也是适合的。</p>
<p>下面是当异常发生时MIPS CPU所做的事情:</p>
<ol>
<li>设置EPC指向回归的位置;</li>
<li>设置SR(EXL)强迫CPU进入kernel态,并禁止所有中断响应。</li>
<li>设置Cause寄存器,以使软件可以得到异常的类型信息;还有其它一些寄存器在某些异常时会被设置;</li>
<li>CPU开始从异常入口取指令,然后以后的所有事情都交由软件处理了。</li>
</ol>
<p>k0和k1寄存器用于保存异常处理函数的地址。</p>
<p>异常处理函数执行完成后,会回到异常分配函数那去,在异常分配函数里,有一个eret指令,用于回归原来被中断的程序继续执行;eret指令会原子性地把中断响应打开(置SR(EXL)),并把状态级由kernel转到user级,并返回原地址继续执行。</p>
<p>异常入口点位于kseg0的底部,是硬件规定的。</p>
<h3 id="异常处理过程-软件部分">异常处理过程-软件部分</h3><p>MIPS的异常处理,通常来说,和其他体系结构的异常/中断/陷阱处理,没有太多的区别,总的来说分为三段:</p>
<ol>
<li>保存现场寄存器组(Register File)。在堆栈中开辟一段区域,将32个通用寄存器和CP0的相关寄存器,如Status,BadVaddr,Cause等,保存在这段内存中。其中尤为重要的是EPC,EPC指向引发异常时的指令。<br>在这个步骤中,首先保存的应该是通用寄存器组,随后是epc/cause/status/badvaddr这几个epc0中的寄存器。从cp0到内存的数据传输必须通过通用寄存器。一般地,编程时的约定是使用k0和k1这两个寄存器暂存。如下例:(适用于32位MIPS模式)</li>
</ol>
<figure class="highlight x86asm"><table><tr><td class="code"><pre><span class="line">sw <span class="preprocessor">zero</span>, <span class="number">0</span>(<span class="literal">sp</span>)</span><br><span class="line">sw <span class="preprocessor">at</span>, <span class="number">4</span>(<span class="literal">sp</span>)</span><br><span class="line">sw v0, <span class="number">8</span>(<span class="literal">sp</span>)</span><br><span class="line">...</span><br><span class="line">sw ra, <span class="number">124</span>(<span class="literal">sp</span>) /*先保存通用寄存器组*/</span><br><span class="line">mfc <span class="literal">k0</span>, epc</span><br><span class="line"><span class="keyword">nop</span> /* mfc太慢,要在延迟槽中加一个<span class="keyword">nop</span> */</span><br><span class="line">sw <span class="literal">k0</span>, <span class="number">128</span>(<span class="literal">sp</span>)</span><br><span class="line">mfc <span class="literal">k0</span>, cause</span><br><span class="line"><span class="keyword">nop</span></span><br><span class="line">sw <span class="literal">k0</span>, <span class="number">132</span>(<span class="literal">sp</span>)</span><br><span class="line">...</span><br></pre></td></tr></table></figure>
<ol>
<li><p>异常处理部分。以Address Error异常为例,当异常发生时,根据保存的BadVaddr,调用两次非对齐加载/存储指令,对内存地址进行数据的读写操作。</p>
</li>
<li><p>返回。将保存在堆栈中的寄存器组内容恢复。<br>从异常状态返回的这个动作,是由硬件完成的。它必须同时完成三个操作:</p>
</li>
</ol>
<ul>
<li>将SR寄存器恢复;</li>
<li>返回到EPC寄存器所指向的地址继续执行;</li>
<li>恢复到用户态。如《See MIPS Run》提到的,如果这三个过程没有能够“原子地”执行完毕,那么将会导致一个安全漏洞,用户有可能在某种情况下僭越CPU内核态设定的壁垒,从而非法获得管理员权限。<br>在MIPS I和MIPS II处理器中,使用rfe这条指令,来进行“从异常中恢复”,也就是恢复SR寄存器,并且将系统从内核态恢复到用户态。但这条指令并没有将执行的指令地址返回到异常发生的指令处。这项工作应当由在此之前的一条JR指令来执行。这样,从异常中返回的相关汇编代码应当为:</li>
</ul>
<figure class="highlight armasm"><table><tr><td class="code"><pre><span class="line"><span class="label">mfc</span> k0, epc</span><br><span class="line"><span class="label">jr</span> k0</span><br><span class="line"><span class="keyword">rfe </span><span class="comment">/* 在上一条jr指令的延迟槽中执行,这样可以保证原子性 */</span></span><br></pre></td></tr></table></figure>
<p>在MIPS III及以后的处理器中,从异常中返回不再需要这样的繁文缛节,只需要一条eret指令便万事俱备了。</p>
<h2 id="MIPS的中断">MIPS的中断</h2><p>MIPS CPU有8个独立的中断位(在Cause寄存器中),其中,6个为外部中断,2个为内部中断(可由软件访问)。一般来说,片上的时钟计数/定时器,会连接到一个硬件位上去。</p>
<p>SR(IE)位控制全局中断响应,为0的话,就禁止所有中断;</p>
<p>SR(EXL)和SR(ERL)位(任何一个)如果置1的话,会禁止中断;</p>
<p>SR(IM)有8位,对应8个中断源,要产生中断,还得把这8位中相应的位置1才行;</p>
<p>中断处理程序也是用通用异常入口。但有些新的CPU有变化。</p>
<p>在软件中实现中断优先级的方案:</p>
<ol>
<li>给各种中断定优先级;</li>
<li>CPU在运行时总是处于某个优先级(即定义一个全局变量);</li>
<li>中断发生时,只有等于高于CPU优先级的中断优先级才能执行;(如果CPU优先级处于最低,那么所有的中断都可以执行);</li>
<li>同时有多个中断发生时,优先执行优先级最高的那个中断程序;</li>
</ol>
<h2 id="MIPS的原子操作">MIPS的原子操作</h2><p>MIPS为支持操作系统的原子操作,特地加了一组指令 ll/sc。它们这样来使用:</p>
<p>先写一句<br><figure class="highlight erlang"><table><tr><td class="code"><pre><span class="line">atomic_block:</span><br><span class="line"><span class="variable">LL</span> <span class="variable">XX1</span>, <span class="variable">XXX2</span></span><br><span class="line">….</span><br><span class="line">sc <span class="variable">XX1</span>, <span class="variable">XXX2</span></span><br><span class="line">beq <span class="variable">XX1</span>, zero, automic_block</span><br><span class="line">….</span><br></pre></td></tr></table></figure></p>
<p>在ll/sc中间写上你要执行的代码体,这样就能保证写入的代码体是原子执行的(不会被抢占的)。</p>
<p>其实,LL/sc两语句自身并不保证原子执行,但它耍了个花招:</p>
<p>用一个临时寄存器XX1,执行LL后,把XXX2中的值载入XX1中,然后会在CPU内部置一个标志位,我们不可见,并保存XXX2的地址,CPU会监视它。在中间的代码体执行的过程中,如果发现XXX2的内容变了(即是别的线程执行了,或是某个中断发生了),就自动把CPU内部那个标志位清0。执行sc 时,把XX1的内容(可能已经是新值了)存入XXX2中,并返回一个值存入XX1中,如果标志位还为1,那么这个返回的值就为1;如果标志位为0,那么这个返回值就为0。为1的话,就表明这对指令中间的代码是一次性执行完成的,而不是中间受到了某些中断,那么原子操作就成功了;为0的话,就表明原子操作没成功,执行后面beq指令时,就会跳转到ll指令重新执行,直到原子操作成功为止。</p>
<p>所以,我们要注意,插在LL/sc指令中间的代码必须短小。</p>
<p>据经验,一般原子操作的循环不会超过3次。</p>
<h2 id="MIPS的大小端">MIPS的大小端</h2><p>硬件上也有大端小端问题,比如串口通讯,一个字节一个字节的发,首先是低位先发出去。</p>
<p>还有显卡的显示,比如显示黑白图像,在屏幕上一个点对应显存中的一位,这时,这个位对应关系就是屏幕右上角那个点对应显存第一个字节的7号位,即最高位。第一排第8位点对应第一个字节的0号位。</p>
<h2 id="MIPS的MMU">MIPS的MMU</h2><h3 id="ASID">ASID</h3><p>ASID是与虚拟页高位配合使用。用于描述在TLB和Cache中的不同的线程,只有8位,所以最多只能同时运行256个线程。这个数字一般来说是够的。如果超过这个数目了,就要把Cache刷新了重新装入。所以,在这点上,与x86是不同的。</p>
<h3 id="TLB的refill过程-硬件部分">TLB的refill过程-硬件部分</h3><ol>
<li><p>CPU先产生一个虚拟地址,要到这个地址所对应的物理地址上取数据(或指令)或写数据(或指令)。</p>
<p>低13位被分开来,然后高19位成为VPN2,和当前线程的ASID(从EntryHi(ASID)取)一起配合与TLB表中的项进行比较(在比较过程中,会受到PageMask和G标志位的影响)。</p>
</li>
<li><p>如果有匹配的项,就选择那个。虚拟地址中的第12位用于选取是用左边的物理地址项还是用右边的物理地址项。</p>
<p>然后就会考察V和D标志位,V标志位表示本页是否有效,D表示本页是否已经脏了(被写过)。<br>如果V=0,或D=1,就会引发翻译异常,BadVAddr会保存现在处理的这个虚拟地址,EntryHi会填入这个虚拟地址的高位,还有Context中的内容会被重填。</p>
<p>然后就会考察C标志位,如果C=1,就会用缓冲作中转,如果C=0,就不使用缓冲。</p>
<p>这几级考察都通过了之后,就正确地找到了那个对应的物理地址。</p>
</li>
<li><p>如果没有匹配的项,就会触发一个TLB refill异常,然后后面就是软件的工作了。</p>
</li>
</ol>
<h3 id="TLB的refill过程-软件部分">TLB的refill过程-软件部分</h3><ol>
<li>计算这个虚拟地址是不是一个正确的虚拟地址,在内存页表中有没有与它对应的物理地址;如果没有,则调用地址错误处理函数;</li>
<li>如果在内存页表中找到了对应的物理地址,就将其载入寄存器;</li>
<li>如果TLB已经满了,就用random选取一个项丢弃;</li>
<li>复制新的项进TLB。</li>
</ol>
<h2 id="MIPS的高速缓冲">MIPS的高速缓冲</h2><p>MIPS一般有两到三级缓冲,其中第一级缓冲数据和指令分开存储。这样的好处是指令和数据可以同时存取,提高效率。但缺点是提高了复杂度。第二级缓冲和第三级缓冲(如果有的话)就不再分开存放啦。</p>
<p>缓冲的单元叫做缓冲行(cache line)。每一行中,有一个tag,然后后面接的是一些标志位和一些数据。缓冲行按顺序线性排列起来,就组成了整个缓冲。</p>
<p>cache line的索引和存取有一套完整的机制。</p>
]]></content>
<summary type="html">
<![CDATA[<h2 id="MIPS指令">MIPS指令</h2><h3 id="MIPS的指令特点">MIPS的指令特点</h3><ol>
<li><p>所有指令都是32位编码;</p>
</li>
<li><p>有些指令有26位供目标地址编码;有些则只有16位。因此要想加载任何一个32位]]>
</summary>
<category term="SylixOS" scheme="jiaojinxing.github.io/tags/SylixOS/"/>
<category term="测试" scheme="jiaojinxing.github.io/tags/%E6%B5%8B%E8%AF%95/"/>
<category term="SylixOS" scheme="jiaojinxing.github.io/categories/SylixOS/"/>
</entry>
<entry>
<title><![CDATA[SylixOS 网络文件系统 nfs 的使用]]></title>
<link href="jiaojinxing.github.io/2015/07/31/SylixOS-%E7%BD%91%E7%BB%9C%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F-nfs-%E7%9A%84%E4%BD%BF%E7%94%A8/"/>
<id>jiaojinxing.github.io/2015/07/31/SylixOS-网络文件系统-nfs-的使用/</id>
<published>2015-07-31T03:16:24.000Z</published>
<updated>2015-07-31T03:51:46.354Z</updated>
<content type="html"><![CDATA[<p>SylixOS 支持网络文件系统 nfs,在开发阶段,当工程文件相当多并修改频繁时,使用 nfs 可以免去频繁下载这些工程文件的麻烦,从而提高开发效率,下面介绍 nfs 的使用方法。</p>
<h2 id="确保_SylixOS_编译了_nfs_组件">确保 SylixOS 编译了 nfs 组件</h2><p>默认情况 SylixOS 开启了 nfs 的支持,但 nfs 可以裁减,查看 sylixos-base/libsylixos/config/fs/fs_cfg.h 文件,找到 LW_CFG_NFS_EN 的定义,确保 LW_CFG_NFS_EN 被定义为 1,如下:<br><figure class="highlight stylus"><table><tr><td class="code"><pre><span class="line"><span class="hexcolor">#def</span>ine LW_CFG_NFS_EN <span class="number">1</span> <span class="comment">/* 是否使能 NFS 文件系统服务 */</span></span><br></pre></td></tr></table></figure></p>
<p>此外,nfs 依赖于如下组件:</p>
<ol>
<li>网络</li>
<li>RPC</li>
<li>I/O 系统</li>
</ol>
<p>需要确保以上组件均已经使能。</p>
<h2 id="主机运行_nfs_服务器">主机运行 nfs 服务器</h2><p>双击 FreeNFS.exe 运行 nfs 服务器,FreeNFS.exe 运行后会退到系统托盘,在系统托盘选中 FreeNFS 的图标,并右键打开快捷菜单,点击 “settings…” 菜单打开设置对话框。</p>
<p>切换到 Server 页面:</p>
<p><img src="/img/SylixOS-网络文件系统-nfs-的使用/图像 1.png" alt="图像 1.png"></p>
<p>Path 输入框输入主机用于 nfs 的目录路径。</p>
<p>切换到 Clients 页面:</p>
<p><img src="/img/SylixOS-网络文件系统-nfs-的使用/图像 2.png" alt="图像 2.png"></p>
<p>Allowed host 输入允许的开发板的 IP 地址,使用空格分隔多个 IP 地址。</p>
<p>切换到 Filenames 页面:</p>
<p><img src="/img/SylixOS-网络文件系统-nfs-的使用/图像 3.png" alt="图像 2.png"></p>
<p>Codepage 选择 “20936 (简体中文 GB2312)”。</p>
<p>最后点击 OK 按钮完成设置。</p>
<h2 id="开发板挂载_nfs">开发板挂载 nfs</h2><p>使用网线连接开发板与主机(或确保开发板与主机在同一网段并可相连)。</p>
<p>在开发板的 shell 执行如下命令:<br><figure class="highlight elixir"><table><tr><td class="code"><pre><span class="line">mount -t nfs <span class="number">192.168</span>.<span class="number">1.10</span><span class="symbol">:/posixtestsuite</span> /mnt/nfs</span><br></pre></td></tr></table></figure></p>
<p>mount 是挂载命令;</p>
<p>-t 指定了文件系统的类型为 nfs;</p>
<p>192.168.1.10:/posixtestsuite 是主机的路径,其中 192.168.1.10 是主机的 IP 地址,<strong>而 /posixtestsuite 是主机的 D:\workspace_opensource\posixtestsuite 目录下存在的子目录</strong>; </p>
<p>/mnt/nfs 是需要挂载到路径,一般情况下我们使用 /mnt 的一个子目录用于挂载,/mnt/nfs 目录在挂载时被创建,所以无需事先创建。</p>
<p>挂载成功后,进入 /mnt/nfs/ 目录,ls 可查看主机 D:\workspace_opensource\posixtestsuite\posixtestsuite 目录下的内容:<br><figure class="highlight elixir"><table><tr><td class="code"><pre><span class="line">[root<span class="variable">@sylixos_station</span><span class="symbol">:/</span>]<span class="comment"># cd /mnt/nfs/</span></span><br><span class="line">[root<span class="variable">@sylixos_station</span><span class="symbol">:/mnt/nfs</span>]<span class="comment"># ls</span></span><br><span class="line"><span class="constant">AUTHORS </span> <span class="constant">BUILD </span> <span class="constant">ChangeLog </span> conformance <span class="constant">COPYING</span></span><br><span class="line"><span class="constant">Documentation </span> exec-func.sh execute.sh functional <span class="keyword">include</span></span><br><span class="line"><span class="constant">INSTALL </span> <span class="constant">LDFLAGS </span> locate-test logfile <span class="constant">Makefile.</span>sylixos</span><br><span class="line"><span class="constant">NEWS </span> posixtestsuite_run_test <span class="constant">QUICK-START </span> <span class="constant">README</span></span><br><span class="line">run_tests sed.exe.stackdump stress t<span class="number">0</span>.c</span><br></pre></td></tr></table></figure></p>
<p>showmount 命令可以查看当前系统挂载的文件系统:<br><figure class="highlight ruby"><table><tr><td class="code"><pre><span class="line">[root<span class="variable">@sylixos_station</span><span class="symbol">:/</span>]<span class="comment"># showmount</span></span><br><span class="line">all mount point show <span class="prompt">>></span><br><span class="line"> </span><span class="constant">VOLUME</span> <span class="constant">BLK</span> <span class="constant">NAME</span></span><br><span class="line">-------------------- --------------------------------</span><br><span class="line"><span class="regexp">/mnt/nfs</span> <span class="number">192.168</span>.<span class="number">1.10</span><span class="symbol">:/posixtestsuite</span></span><br><span class="line">/ramdisk <span class="number">0</span></span><br></pre></td></tr></table></figure></p>
<p>df 命令可以查看文件系统的大小、空闲空间、使用百分比及类型:<br><figure class="highlight brainfuck"><table><tr><td class="code"><pre><span class="line"><span class="title">[</span><span class="comment">root@sylixos_station:/</span><span class="title">]</span><span class="comment">#</span> <span class="comment">df</span> <span class="comment">/mnt/nfs/</span></span><br><span class="line"> <span class="comment">VOLUME</span> <span class="comment">TOTAL</span> <span class="comment">FREE</span> <span class="comment">USED</span> <span class="comment">RO</span> <span class="comment">FS</span> <span class="comment">TYPE</span></span><br><span class="line"><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span> <span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span> <span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span> <span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span> <span class="literal">-</span><span class="literal">-</span> <span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span><span class="literal">-</span></span><br><span class="line"><span class="comment">/mnt/nfs/</span> <span class="comment">443</span><span class="string">.</span><span class="comment">22GB</span> <span class="comment">359</span><span class="string">.</span><span class="comment">69GB</span> <span class="comment">18%</span> <span class="comment">n</span> <span class="comment">NFSv3</span> <span class="comment">FileSystem</span></span><br></pre></td></tr></table></figure></p>
<p>umount 命令可以取消挂载文件系统:<br><figure class="highlight ruby"><table><tr><td class="code"><pre><span class="line">[root<span class="variable">@sylixos_station</span><span class="symbol">:/</span>]<span class="comment"># umount /mnt/nfs/</span></span><br><span class="line">[root<span class="variable">@sylixos_station</span><span class="symbol">:/</span>]<span class="comment"># showmount</span></span><br><span class="line">all mount point show <span class="prompt">>></span><br><span class="line"> </span><span class="constant">VOLUME</span> <span class="constant">BLK</span> <span class="constant">NAME</span></span><br><span class="line">-------------------- --------------------------------</span><br><span class="line"><span class="regexp">/ramdisk 0</span></span><br></pre></td></tr></table></figure></p>
]]></content>
<summary type="html">
<![CDATA[<p>SylixOS 支持网络文件系统 nfs,在开发阶段,当工程文件相当多并修改频繁时,使用 nfs 可以免去频繁下载这些工程文件的麻烦,从而提高开发效率,下面介绍 nfs 的使用方法。</p>
<h2 id="确保_SylixOS_编译了_nfs_组件">确保 SylixOS]]>
</summary>
<category term="SylixOS" scheme="jiaojinxing.github.io/tags/SylixOS/"/>
<category term="SylixOS" scheme="jiaojinxing.github.io/categories/SylixOS/"/>
</entry>
<entry>
<title><![CDATA[Hello World]]></title>
<link href="jiaojinxing.github.io/2015/07/19/hello-world/"/>
<id>jiaojinxing.github.io/2015/07/19/hello-world/</id>
<published>2015-07-19T04:10:45.415Z</published>
<updated>2015-07-19T04:10:45.415Z</updated>
<content type="html"><![CDATA[<p>Markdown 编辑器:mdcharm(<a href="http://www.mdcharm.com/" target="_blank" rel="external">http://www.mdcharm.com/</a>)</p>
<p>Markdown 语法:<a href="http://wowubuntu.com/markdown/" target="_blank" rel="external">http://wowubuntu.com/markdown/</a></p>
<p>表格语法:</p>
<figure class="highlight gherkin"><table><tr><td class="code"><pre><span class="line">|<span class="string">宏名 </span>|<span class="string">含义</span>|</span><br><span class="line">|<span class="string">--- </span>|<span class="string">:---</span>|</span><br><span class="line">|<span class="string">LW_OPTION_NOT_WAIT </span>|<span class="string">不等待立即退出</span>|</span><br><span class="line">|<span class="string">LW_OPTION_WAIT_INFINITE </span>|<span class="string">永远等待</span>|</span><br><span class="line">|<span class="string">LW_OPTION_WAIT_A_TICK </span>|<span class="string">等待一个时钟嘀嗒</span>|</span><br><span class="line">|<span class="string">LW_OPTION_WAIT_A_SECOND </span>|<span class="string">等待一秒</span>|</span><br></pre></td></tr></table></figure>
<p>表格效果:</p>
<table>
<thead>
<tr>
<th>宏名</th>
<th style="text-align:left">含义</th>
</tr>
</thead>
<tbody>
<tr>
<td>LW_OPTION_NOT_WAIT</td>
<td style="text-align:left">不等待立即退出</td>
</tr>
<tr>
<td>LW_OPTION_WAIT_INFINITE</td>
<td style="text-align:left">永远等待</td>
</tr>
<tr>
<td>LW_OPTION_WAIT_A_TICK</td>
<td style="text-align:left">等待一个时钟嘀嗒</td>
</tr>
<tr>
<td>LW_OPTION_WAIT_A_SECOND</td>
<td style="text-align:left">等待一秒</td>
</tr>
</tbody>
</table>
<p>plantuml 语法:<a href="http://plantuml.sourceforge.net/" target="_blank" rel="external">http://plantuml.sourceforge.net/</a></p>
<p>PC 上使用 Eclipse 插件 plantuml - <a href="http://plantuml.sourceforge.net/updatesite/" target="_blank" rel="external">http://plantuml.sourceforge.net/updatesite/</a> </p>
<p>plantuml 生成 UML 图的例子:</p>
<figure class="highlight groovy"><table><tr><td class="code"><pre><span class="line">{% plantuml %}</span><br><span class="line"></span><br><span class="line"><span class="annotation">@startuml</span></span><br><span class="line">Alice -> <span class="string">Bob:</span> Authentication Request</span><br><span class="line">Bob --> <span class="string">Alice:</span> Authentication Response</span><br><span class="line"></span><br><span class="line">Alice -> <span class="string">Bob:</span> Another authentication Request</span><br><span class="line">Alice <-- <span class="string">Bob:</span> another authentication Response</span><br><span class="line"><span class="annotation">@enduml</span></span><br><span class="line"></span><br><span class="line">{% endplantuml %}</span><br></pre></td></tr></table></figure>
<img src="http://www.plantuml.com/plantuml/svg/TSx13O0W38NXErDqWIvWZ057S0F49f9WKIZxIyIJmVFxykVfB3P9EO8omJi2d62Ewm2co4uitbdnaM6Xgr0MLJV0QXxSKVcCd4bzOnohIs3xqOP7nARjdtxZcdYhXsy0">
<p>plantuml 使用 DOT 语法生成流程图的例子:</p>
<figure class="highlight armasm"><table><tr><td class="code"><pre><span class="line">{% plantuml %}</span><br><span class="line"></span><br><span class="line"><span class="comment">@startuml</span></span><br><span class="line"><span class="label">digraph</span> G {</span><br><span class="line"> <span class="keyword">subgraph </span>cluster0 {</span><br><span class="line"> node [style<span class="label">=filled</span>,color<span class="label">=white</span>]<span class="comment">;</span></span><br><span class="line"> style<span class="label">=filled</span><span class="comment">;</span></span><br><span class="line"> color<span class="label">=lightgrey</span><span class="comment">;</span></span><br><span class="line"> a0 -> <span class="literal">a1</span> -> <span class="literal">a2</span> -> <span class="literal">a3</span><span class="comment">;</span></span><br><span class="line"> label = <span class="string">"process #1"</span><span class="comment">;</span></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">subgraph </span>cluster1 {</span><br><span class="line"> node [style<span class="label">=filled</span>]<span class="comment">;</span></span><br><span class="line"> <span class="keyword">b0 </span>-> <span class="keyword">b1 </span>-> <span class="keyword">b2 </span>-> <span class="keyword">b3;</span><br><span class="line"></span> label = <span class="string">"process #2"</span><span class="comment">;</span></span><br><span class="line"> color<span class="label">=blue</span></span><br><span class="line"> }</span><br><span class="line"> start -> a0<span class="comment">;</span></span><br><span class="line"> start -> <span class="keyword">b0;</span><br><span class="line"></span> <span class="literal">a1</span> -> <span class="keyword">b3;</span><br><span class="line"></span> <span class="keyword">b2 </span>-> <span class="literal">a3</span><span class="comment">;</span></span><br><span class="line"> <span class="literal">a3</span> -> a0<span class="comment">;</span></span><br><span class="line"> <span class="literal">a3</span> -> <span class="preprocessor">end</span><span class="comment">;</span></span><br><span class="line"> <span class="keyword">b3 </span>-> <span class="preprocessor">end</span><span class="comment">;</span></span><br><span class="line"> start [shape<span class="label">=Mdiamond</span>]<span class="comment">;</span></span><br><span class="line"> <span class="preprocessor">end</span> [shape<span class="label">=Msquare</span>]<span class="comment">;</span></span><br><span class="line">}</span><br><span class="line"><span class="comment">@enduml</span></span><br><span class="line"></span><br><span class="line">{% endplantuml %}</span><br></pre></td></tr></table></figure>
<img src="http://www.plantuml.com/plantuml/svg/VL7BReD03Bpp5HQvfX8anuWgjvxo1QW76rnOoM79FbH5KVuzi4i2L5LyiEJnxCxOFbg7nlcp9BLg3FOjVC4jWI6ifmXKugrZaqtu69sk6KhhhiB5ZnBXUbjfqQRuRPNZxyEBkAJCQEIAQbhN6BxE3SpWunCm3taNydxk2X8B593sHbTiBMpoD7Rl_phEtpfUkAGWIq6MWYozbTsbVsSXyRnqCYursCyEQu0c8CxubA7LhBXVFeqLTzF-Q5t6ZqlROi_5gLPurjrpj87qwjYBHpDUvfuS1tmu-0C0">
<p>也可以使用 Graphviz <a href="http://www.graphviz.org/" target="_blank" rel="external">http://www.graphviz.org/</a> ,而不使用 plantuml 插件,但只能用 DOT 语法。</p>
]]></content>
<summary type="html">
<![CDATA[<p>Markdown 编辑器:mdcharm(<a href="http://www.mdcharm.com/" target="_blank" rel="external">http://www.mdcharm.com/</a>)</p>
<p>Markdown 语法:<a ]]>
</summary>
</entry>
<entry>
<title><![CDATA[SylixOS ARMv7A 处理器性能测试与改进]]></title>
<link href="jiaojinxing.github.io/2015/07/17/SylixOS-ARMv7A-%E5%A4%84%E7%90%86%E5%99%A8%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95%E4%B8%8E%E6%94%B9%E8%BF%9B/"/>
<id>jiaojinxing.github.io/2015/07/17/SylixOS-ARMv7A-处理器性能测试与改进/</id>
<published>2015-07-17T13:24:31.000Z</published>
<updated>2015-07-29T13:04:11.283Z</updated>
<content type="html"><![CDATA[<h2 id="测试目的">测试目的</h2><p>验证 SylixOS 是否发挥 ARMv7A Cache、VFP、NEON、分支预测性能,验证 BSP 是否在内存控制器、CPU 主频设置方面存在不正确的地方。</p>
<p>找出 SylixOS 实时性远优于 Linux 和 Linux+RT(见《SylixOS实时性测评报告》,但 Qt 性能测试 <a href="https://github.com/jiaojinxing/qtperf" target="_blank" rel="external">qtperf</a> 不如 Linux 的原因,并提出解决办法。</p>
<h2 id="测试环境">测试环境</h2><h3 id="硬件平台">硬件平台</h3><p>硬件平台:飞凌嵌入式 OK335xS</p>
<p>处理器:AM335x(Cortex-A8, 800MHz)</p>
<p>L1-Cache:32KB I-Cache/32KB D-Cache</p>
<p>L2-Cache:256KB</p>
<p>内存:512MB</p>
<h3 id="操作系统">操作系统</h3><p>SylixOS + bspam335x:2015/7/15 </p>
<p>对比测试操作系统 Linux:3.2.0(厂家配套的)</p>
<h3 id="编译器">编译器</h3><p>Linux:</p>
<p>arm-arago-linux-gnueabi-gcc: gcc version 4.5.3 20110311 (prerelease) (GCC)(厂家配套的)</p>
<p>SylixOS:</p>
<p>arm-sylixos-eabi-gcc: gcc version 4.9.3 20150303 (release) [ARM/embedded-4_9-branch revision 221220] (<br>SylixOS Toolchain for ARM Embedded Processors) </p>
<h2 id="测试软件">测试软件</h2><p><a href="http://www.tux.org/~mayer/linux/bmark.html" target="_blank" rel="external">nbench</a> 是一个简单的用于测试处理器、存储器性能的基准测试程序,即著名的 BYTE Magazine 杂志的 BYTEmark benchmark program。</p>
<p>nbench 在系统中运行并将结果和一台运行 Linux 的 AMD K6-233 电脑比较,得到的比值作为性能指数。</p>
<p>由于是完全开源的,爱好者可以在各种平台和操作系统上运行 nbench,并进行优化和测试,是一个简单有效的性能测试工具。</p>
<p>nbench 的结果主要分为 MEM、INT 和 FP,其中 MEM 指数主要体现处理器总线、CACHE 和存储器性能,INT 当然是整数处理性能,FP 则体现双精度浮点性能(大多数嵌入式处理器都没有强大的双精度浮点能力)。</p>
<figure class="highlight smali"><table><tr><td class="code"><pre><span class="line">Numeric sort - Sorts an<span class="instruction"> array </span>of<span class="instruction"> long </span>integers.</span><br><span class="line"></span><br><span class="line">String sort - Sorts an<span class="instruction"> array </span>of strings of arbitrary length.</span><br><span class="line"></span><br><span class="line">Bitfield - Executes a variety of bit manipulation functions.</span><br><span class="line"></span><br><span class="line">Emulated floating-point - A small software floating-point package.</span><br><span class="line"></span><br><span class="line">Fourier coefficients - A numerical analysis routine for calculating series approximations of waveforms.</span><br><span class="line"></span><br><span class="line">Assignment algorithm - A well-known task allocation algorithm.</span><br><span class="line"></span><br><span class="line">Huffman compression - A well-known text<span class="instruction"> and </span>graphics compression algorithm.</span><br><span class="line"></span><br><span class="line">IDEA encryption - A relatively<span class="instruction"> new </span>block cipher algorithm.</span><br><span class="line"></span><br><span class="line">Neural Net - A small but functional back-propagation network simulator.</span><br><span class="line"></span><br><span class="line">LU Decomposition - A robust algorithm for solving linear equations.</span><br></pre></td></tr></table></figure>
<p>使用版本:2.2.3</p>
<h2 id="Linux测试结果">Linux测试结果</h2><h3 id="arm-arago-linux-gnueabi-gcc_-mcpu=cortex-a8_-mfloat-abi=softfp_-mfpu=vfpv3_-O3">arm-arago-linux-gnueabi-gcc -mcpu=cortex-a8 -mfloat-abi=softfp -mfpu=vfpv3 -O3</h3><figure class="highlight elixir"><table><tr><td class="code"><pre><span class="line">root<span class="variable">@ok335x</span><span class="symbol">:/home/forlinx</span><span class="comment"># ./nbench</span></span><br><span class="line"></span><br><span class="line"><span class="constant">BYTEmark*</span> <span class="constant">Native Mode Benchmark </span>ver. <span class="number">2</span> (<span class="number">10</span>/<span class="number">95</span>)</span><br><span class="line"><span class="constant">Index-</span>split by <span class="constant">Andrew D.</span> <span class="constant">Balsa </span>(<span class="number">11</span>/<span class="number">97</span>)</span><br><span class="line"><span class="constant">Linux/Unix*</span> port by <span class="constant">Uwe F.</span> <span class="constant">Mayer </span>(<span class="number">12</span>/<span class="number">96</span>,<span class="number">11</span>/<span class="number">97</span>)</span><br><span class="line"></span><br><span class="line"><span class="constant">TEST </span> <span class="symbol">:</span> <span class="constant">Iterations/</span>sec. <span class="symbol">:</span> <span class="constant">Old Index </span> <span class="symbol">:</span> <span class="constant">New Index</span></span><br><span class="line"> <span class="symbol">:</span> <span class="symbol">:</span> <span class="constant">Pentium </span><span class="number">90</span>* <span class="symbol">:</span> <span class="constant">AMD K6/</span><span class="number">233</span>*</span><br><span class="line">--------------------<span class="symbol">:------------------</span><span class="symbol">:-------------</span><span class="symbol">:------------</span></span><br><span class="line"><span class="constant">NUMERIC SORT </span> <span class="symbol">:</span> <span class="number">395.2</span> <span class="symbol">:</span> <span class="number">10.14</span> <span class="symbol">:</span> <span class="number">3.33</span></span><br><span class="line"><span class="constant">STRING SORT </span> <span class="symbol">:</span> <span class="number">40.032</span> <span class="symbol">:</span> <span class="number">17.89</span> <span class="symbol">:</span> <span class="number">2.77</span></span><br><span class="line"><span class="constant">BITFIELD </span> <span class="symbol">:</span> <span class="number">1.3728</span>e+08 <span class="symbol">:</span> <span class="number">23.55</span> <span class="symbol">:</span> <span class="number">4.92</span></span><br><span class="line"><span class="constant">FP EMULATION </span> <span class="symbol">:</span> <span class="number">67.8</span> <span class="symbol">:</span> <span class="number">32.53</span> <span class="symbol">:</span> <span class="number">7.51</span></span><br><span class="line"><span class="constant">FOURIER </span> <span class="symbol">:</span> <span class="number">1324.1</span> <span class="symbol">:</span> <span class="number">1.51</span> <span class="symbol">:</span> <span class="number">0</span>.<span class="number">85</span></span><br><span class="line"><span class="constant">ASSIGNMENT </span> <span class="symbol">:</span> <span class="number">5.2366</span> <span class="symbol">:</span> <span class="number">19.93</span> <span class="symbol">:</span> <span class="number">5.17</span></span><br><span class="line"><span class="constant">IDEA </span> <span class="symbol">:</span> <span class="number">840.3</span> <span class="symbol">:</span> <span class="number">12.85</span> <span class="symbol">:</span> <span class="number">3.82</span></span><br><span class="line"><span class="constant">HUFFMAN </span> <span class="symbol">:</span> <span class="number">514.44</span> <span class="symbol">:</span> <span class="number">14.27</span> <span class="symbol">:</span> <span class="number">4.56</span></span><br><span class="line"><span class="constant">NEURAL NET </span> <span class="symbol">:</span> <span class="number">1.42</span> <span class="symbol">:</span> <span class="number">2.28</span> <span class="symbol">:</span> <span class="number">0</span>.<span class="number">96</span></span><br><span class="line"><span class="constant">LU DECOMPOSITION </span> <span class="symbol">:</span> <span class="number">55.316</span> <span class="symbol">:</span> <span class="number">2.87</span> <span class="symbol">:</span> <span class="number">2.07</span></span><br><span class="line">==========================<span class="constant">ORIGINAL BYTEMARK RESULTS=</span>=========================</span><br><span class="line"><span class="constant">INTEGER INDEX </span> <span class="symbol">:</span> <span class="number">17.524</span></span><br><span class="line"><span class="constant">FLOATING-POINT INDEX:</span> <span class="number">2.143</span></span><br><span class="line"><span class="constant">Baseline </span>(<span class="constant">MSDOS*</span>) <span class="symbol">:</span> <span class="constant">Pentium*</span> <span class="number">90</span>, <span class="number">256</span> <span class="constant">KB L2-</span>cache, <span class="constant">Watcom*</span> compiler <span class="number">10.0</span></span><br><span class="line">==============================<span class="constant">LINUX DATA BELOW=</span>==============================</span><br><span class="line"><span class="constant">CPU </span> <span class="symbol">:</span></span><br><span class="line"><span class="constant">L2 Cache </span> <span class="symbol">:</span></span><br><span class="line"><span class="constant">OS </span> <span class="symbol">:</span> <span class="constant">Linux </span><span class="number">3.2</span>.<span class="number">0</span></span><br><span class="line"><span class="constant">C </span>compiler <span class="symbol">:</span> arm-arago-linux-gnueabi-gcc</span><br><span class="line">libc <span class="symbol">:</span> static</span><br><span class="line"><span class="constant">MEMORY INDEX </span> <span class="symbol">:</span> <span class="number">4.129</span></span><br><span class="line"><span class="constant">INTEGER INDEX </span> <span class="symbol">:</span> <span class="number">4.565</span></span><br><span class="line"><span class="constant">FLOATING-POINT INDEX:</span> <span class="number">1.189</span></span><br><span class="line"><span class="constant">Baseline </span>(<span class="constant">LINUX)</span> <span class="symbol">:</span> <span class="constant">AMD K6/</span><span class="number">233</span>*, <span class="number">512</span> <span class="constant">KB L2-</span>cache, gcc <span class="number">2.7</span>.<span class="number">2.3</span>, libc-<span class="number">5.4</span>.<span class="number">38</span></span><br><span class="line">* <span class="constant">Trademarks </span>are property of their respective holder.</span><br></pre></td></tr></table></figure>
<h3 id="arm-arago-linux-gnueabi-gcc_-mcpu=cortex-a8_-mfloat-abi=softfp_-mfpu=neon_-O3">arm-arago-linux-gnueabi-gcc -mcpu=cortex-a8 -mfloat-abi=softfp -mfpu=neon -O3</h3><figure class="highlight elixir"><table><tr><td class="code"><pre><span class="line">root<span class="variable">@ok335x</span><span class="symbol">:/home/forlinx</span><span class="comment"># ./nbench</span></span><br><span class="line"></span><br><span class="line"><span class="constant">BYTEmark*</span> <span class="constant">Native Mode Benchmark </span>ver. <span class="number">2</span> (<span class="number">10</span>/<span class="number">95</span>)</span><br><span class="line"><span class="constant">Index-</span>split by <span class="constant">Andrew D.</span> <span class="constant">Balsa </span>(<span class="number">11</span>/<span class="number">97</span>)</span><br><span class="line"><span class="constant">Linux/Unix*</span> port by <span class="constant">Uwe F.</span> <span class="constant">Mayer </span>(<span class="number">12</span>/<span class="number">96</span>,<span class="number">11</span>/<span class="number">97</span>)</span><br><span class="line"></span><br><span class="line"><span class="constant">TEST </span> <span class="symbol">:</span> <span class="constant">Iterations/</span>sec. <span class="symbol">:</span> <span class="constant">Old Index </span> <span class="symbol">:</span> <span class="constant">New Index</span></span><br><span class="line"> <span class="symbol">:</span> <span class="symbol">:</span> <span class="constant">Pentium </span><span class="number">90</span>* <span class="symbol">:</span> <span class="constant">AMD K6/</span><span class="number">233</span>*</span><br><span class="line">--------------------<span class="symbol">:------------------</span><span class="symbol">:-------------</span><span class="symbol">:------------</span></span><br><span class="line"><span class="constant">NUMERIC SORT </span> <span class="symbol">:</span> <span class="number">395.52</span> <span class="symbol">:</span> <span class="number">10.14</span> <span class="symbol">:</span> <span class="number">3.33</span></span><br><span class="line"><span class="constant">STRING SORT </span> <span class="symbol">:</span> <span class="number">34.784</span> <span class="symbol">:</span> <span class="number">15.54</span> <span class="symbol">:</span> <span class="number">2.41</span></span><br><span class="line"><span class="constant">BITFIELD </span> <span class="symbol">:</span> <span class="number">1.3741</span>e+08 <span class="symbol">:</span> <span class="number">23.57</span> <span class="symbol">:</span> <span class="number">4.92</span></span><br><span class="line"><span class="constant">FP EMULATION </span> <span class="symbol">:</span> <span class="number">67.746</span> <span class="symbol">:</span> <span class="number">32.51</span> <span class="symbol">:</span> <span class="number">7.50</span></span><br><span class="line"><span class="constant">FOURIER </span> <span class="symbol">:</span> <span class="number">1324.1</span> <span class="symbol">:</span> <span class="number">1.51</span> <span class="symbol">:</span> <span class="number">0</span>.<span class="number">85</span></span><br><span class="line"><span class="constant">ASSIGNMENT </span> <span class="symbol">:</span> <span class="number">5.3171</span> <span class="symbol">:</span> <span class="number">20.23</span> <span class="symbol">:</span> <span class="number">5.25</span></span><br><span class="line"><span class="constant">IDEA </span> <span class="symbol">:</span> <span class="number">840</span> <span class="symbol">:</span> <span class="number">12.85</span> <span class="symbol">:</span> <span class="number">3.81</span></span><br><span class="line"><span class="constant">HUFFMAN </span> <span class="symbol">:</span> <span class="number">514.24</span> <span class="symbol">:</span> <span class="number">14.26</span> <span class="symbol">:</span> <span class="number">4.55</span></span><br><span class="line"><span class="constant">NEURAL NET </span> <span class="symbol">:</span> <span class="number">1.4205</span> <span class="symbol">:</span> <span class="number">2.28</span> <span class="symbol">:</span> <span class="number">0</span>.<span class="number">96</span></span><br><span class="line"><span class="constant">LU DECOMPOSITION </span> <span class="symbol">:</span> <span class="number">54.778</span> <span class="symbol">:</span> <span class="number">2.84</span> <span class="symbol">:</span> <span class="number">2.05</span></span><br><span class="line">==========================<span class="constant">ORIGINAL BYTEMARK RESULTS=</span>=========================</span><br><span class="line"><span class="constant">INTEGER INDEX </span> <span class="symbol">:</span> <span class="number">17.213</span></span><br><span class="line"><span class="constant">FLOATING-POINT INDEX:</span> <span class="number">2.136</span></span><br><span class="line"><span class="constant">Baseline </span>(<span class="constant">MSDOS*</span>) <span class="symbol">:</span> <span class="constant">Pentium*</span> <span class="number">90</span>, <span class="number">256</span> <span class="constant">KB L2-</span>cache, <span class="constant">Watcom*</span> compiler <span class="number">10.0</span></span><br><span class="line">==============================<span class="constant">LINUX DATA BELOW=</span>==============================</span><br><span class="line"><span class="constant">CPU </span> <span class="symbol">:</span></span><br><span class="line"><span class="constant">L2 Cache </span> <span class="symbol">:</span></span><br><span class="line"><span class="constant">OS </span> <span class="symbol">:</span> <span class="constant">Linux </span><span class="number">3.2</span>.<span class="number">0</span></span><br><span class="line"><span class="constant">C </span>compiler <span class="symbol">:</span> arm-arago-linux-gnueabi-gcc</span><br><span class="line">libc <span class="symbol">:</span> static</span><br><span class="line"><span class="constant">MEMORY INDEX </span> <span class="symbol">:</span> <span class="number">3.961</span></span><br><span class="line"><span class="constant">INTEGER INDEX </span> <span class="symbol">:</span> <span class="number">4.564</span></span><br><span class="line"><span class="constant">FLOATING-POINT INDEX:</span> <span class="number">1.185</span></span><br><span class="line"><span class="constant">Baseline </span>(<span class="constant">LINUX)</span> <span class="symbol">:</span> <span class="constant">AMD K6/</span><span class="number">233</span>*, <span class="number">512</span> <span class="constant">KB L2-</span>cache, gcc <span class="number">2.7</span>.<span class="number">2.3</span>, libc-<span class="number">5.4</span>.<span class="number">38</span></span><br><span class="line">* <span class="constant">Trademarks </span>are property of their respective holder.</span><br></pre></td></tr></table></figure>
<h3 id="arm-arago-linux-gnueabi-gcc_-mcpu=cortex-a8_-O3">arm-arago-linux-gnueabi-gcc -mcpu=cortex-a8 -O3</h3><figure class="highlight elixir"><table><tr><td class="code"><pre><span class="line">root<span class="variable">@ok335x</span><span class="symbol">:/home/forlinx</span><span class="comment"># ./nbench</span></span><br><span class="line"></span><br><span class="line"><span class="constant">BYTEmark*</span> <span class="constant">Native Mode Benchmark </span>ver. <span class="number">2</span> (<span class="number">10</span>/<span class="number">95</span>)</span><br><span class="line"><span class="constant">Index-</span>split by <span class="constant">Andrew D.</span> <span class="constant">Balsa </span>(<span class="number">11</span>/<span class="number">97</span>)</span><br><span class="line"><span class="constant">Linux/Unix*</span> port by <span class="constant">Uwe F.</span> <span class="constant">Mayer </span>(<span class="number">12</span>/<span class="number">96</span>,<span class="number">11</span>/<span class="number">97</span>)</span><br><span class="line"></span><br><span class="line"><span class="constant">TEST </span> <span class="symbol">:</span> <span class="constant">Iterations/</span>sec. <span class="symbol">:</span> <span class="constant">Old Index </span> <span class="symbol">:</span> <span class="constant">New Index</span></span><br><span class="line"> <span class="symbol">:</span> <span class="symbol">:</span> <span class="constant">Pentium </span><span class="number">90</span>* <span class="symbol">:</span> <span class="constant">AMD K6/</span><span class="number">233</span>*</span><br><span class="line">--------------------<span class="symbol">:------------------</span><span class="symbol">:-------------</span><span class="symbol">:------------</span></span><br><span class="line"><span class="constant">NUMERIC SORT </span> <span class="symbol">:</span> <span class="number">394.88</span> <span class="symbol">:</span> <span class="number">10.13</span> <span class="symbol">:</span> <span class="number">3.33</span></span><br><span class="line"><span class="constant">STRING SORT </span> <span class="symbol">:</span> <span class="number">39.968</span> <span class="symbol">:</span> <span class="number">17.86</span> <span class="symbol">:</span> <span class="number">2.76</span></span><br><span class="line"><span class="constant">BITFIELD </span> <span class="symbol">:</span> <span class="number">1.3734</span>e+08 <span class="symbol">:</span> <span class="number">23.56</span> <span class="symbol">:</span> <span class="number">4.92</span></span><br><span class="line"><span class="constant">FP EMULATION </span> <span class="symbol">:</span> <span class="number">67.773</span> <span class="symbol">:</span> <span class="number">32.52</span> <span class="symbol">:</span> <span class="number">7.50</span></span><br><span class="line"><span class="constant">FOURIER </span> <span class="symbol">:</span> <span class="number">1324.1</span> <span class="symbol">:</span> <span class="number">1.51</span> <span class="symbol">:</span> <span class="number">0</span>.<span class="number">85</span></span><br><span class="line"><span class="constant">ASSIGNMENT </span> <span class="symbol">:</span> <span class="number">5.2469</span> <span class="symbol">:</span> <span class="number">19.97</span> <span class="symbol">:</span> <span class="number">5.18</span></span><br><span class="line"><span class="constant">IDEA </span> <span class="symbol">:</span> <span class="number">840</span> <span class="symbol">:</span> <span class="number">12.85</span> <span class="symbol">:</span> <span class="number">3.81</span></span><br><span class="line"><span class="constant">HUFFMAN </span> <span class="symbol">:</span> <span class="number">514.44</span> <span class="symbol">:</span> <span class="number">14.27</span> <span class="symbol">:</span> <span class="number">4.56</span></span><br><span class="line"><span class="constant">NEURAL NET </span> <span class="symbol">:</span> <span class="number">1.4015</span> <span class="symbol">:</span> <span class="number">2.25</span> <span class="symbol">:</span> <span class="number">0</span>.<span class="number">95</span></span><br><span class="line"><span class="constant">LU DECOMPOSITION </span> <span class="symbol">:</span> <span class="number">55.196</span> <span class="symbol">:</span> <span class="number">2.86</span> <span class="symbol">:</span> <span class="number">2.06</span></span><br><span class="line">==========================<span class="constant">ORIGINAL BYTEMARK RESULTS=</span>=========================</span><br><span class="line"><span class="constant">INTEGER INDEX </span> <span class="symbol">:</span> <span class="number">17.522</span></span><br><span class="line"><span class="constant">FLOATING-POINT INDEX:</span> <span class="number">2.132</span></span><br><span class="line"><span class="constant">Baseline </span>(<span class="constant">MSDOS*</span>) <span class="symbol">:</span> <span class="constant">Pentium*</span> <span class="number">90</span>, <span class="number">256</span> <span class="constant">KB L2-</span>cache, <span class="constant">Watcom*</span> compiler <span class="number">10.0</span></span><br><span class="line">==============================<span class="constant">LINUX DATA BELOW=</span>==============================</span><br><span class="line"><span class="constant">CPU </span> <span class="symbol">:</span></span><br><span class="line"><span class="constant">L2 Cache </span> <span class="symbol">:</span></span><br><span class="line"><span class="constant">OS </span> <span class="symbol">:</span> <span class="constant">Linux </span><span class="number">3.2</span>.<span class="number">0</span></span><br><span class="line"><span class="constant">C </span>compiler <span class="symbol">:</span> arm-arago-linux-gnueabi-gcc</span><br><span class="line">libc <span class="symbol">:</span> static</span><br><span class="line"><span class="constant">MEMORY INDEX </span> <span class="symbol">:</span> <span class="number">4.130</span></span><br><span class="line"><span class="constant">INTEGER INDEX </span> <span class="symbol">:</span> <span class="number">4.563</span></span><br><span class="line"><span class="constant">FLOATING-POINT INDEX:</span> <span class="number">1.183</span></span><br><span class="line"><span class="constant">Baseline </span>(<span class="constant">LINUX)</span> <span class="symbol">:</span> <span class="constant">AMD K6/</span><span class="number">233</span>*, <span class="number">512</span> <span class="constant">KB L2-</span>cache, gcc <span class="number">2.7</span>.<span class="number">2.3</span>, libc-<span class="number">5.4</span>.<span class="number">38</span></span><br><span class="line">* <span class="constant">Trademarks </span>are property of their respective holder.</span><br></pre></td></tr></table></figure>
<h3 id="arm-arago-linux-gnueabi-gcc_-mcpu=arm920t_-O3">arm-arago-linux-gnueabi-gcc -mcpu=arm920t -O3</h3><figure class="highlight elixir"><table><tr><td class="code"><pre><span class="line">root<span class="variable">@ok335x</span><span class="symbol">:/home/forlinx</span><span class="comment"># ./nbench</span></span><br><span class="line"></span><br><span class="line"><span class="constant">BYTEmark*</span> <span class="constant">Native Mode Benchmark </span>ver. <span class="number">2</span> (<span class="number">10</span>/<span class="number">95</span>)</span><br><span class="line"><span class="constant">Index-</span>split by <span class="constant">Andrew D.</span> <span class="constant">Balsa </span>(<span class="number">11</span>/<span class="number">97</span>)</span><br><span class="line"><span class="constant">Linux/Unix*</span> port by <span class="constant">Uwe F.</span> <span class="constant">Mayer </span>(<span class="number">12</span>/<span class="number">96</span>,<span class="number">11</span>/<span class="number">97</span>)</span><br><span class="line"></span><br><span class="line"><span class="constant">TEST </span> <span class="symbol">:</span> <span class="constant">Iterations/</span>sec. <span class="symbol">:</span> <span class="constant">Old Index </span> <span class="symbol">:</span> <span class="constant">New Index</span></span><br><span class="line"> <span class="symbol">:</span> <span class="symbol">:</span> <span class="constant">Pentium </span><span class="number">90</span>* <span class="symbol">:</span> <span class="constant">AMD K6/</span><span class="number">233</span>*</span><br><span class="line">--------------------<span class="symbol">:------------------</span><span class="symbol">:-------------</span><span class="symbol">:------------</span></span><br><span class="line"><span class="constant">NUMERIC SORT </span> <span class="symbol">:</span> <span class="number">386.08</span> <span class="symbol">:</span> <span class="number">9.90</span> <span class="symbol">:</span> <span class="number">3.25</span></span><br><span class="line"><span class="constant">STRING SORT </span> <span class="symbol">:</span> <span class="number">39.306</span> <span class="symbol">:</span> <span class="number">17.56</span> <span class="symbol">:</span> <span class="number">2.72</span></span><br><span class="line"><span class="constant">BITFIELD </span> <span class="symbol">:</span> <span class="number">1.1958</span>e+08 <span class="symbol">:</span> <span class="number">20.51</span> <span class="symbol">:</span> <span class="number">4.28</span></span><br><span class="line"><span class="constant">FP EMULATION </span> <span class="symbol">:</span> <span class="number">61.975</span> <span class="symbol">:</span> <span class="number">29.74</span> <span class="symbol">:</span> <span class="number">6.86</span></span><br><span class="line"><span class="constant">FOURIER </span> <span class="symbol">:</span> <span class="number">1315.8</span> <span class="symbol">:</span> <span class="number">1.50</span> <span class="symbol">:</span> <span class="number">0</span>.<span class="number">84</span></span><br><span class="line"><span class="constant">ASSIGNMENT </span> <span class="symbol">:</span> <span class="number">5.5866</span> <span class="symbol">:</span> <span class="number">21.26</span> <span class="symbol">:</span> <span class="number">5.51</span></span><br><span class="line"><span class="constant">IDEA </span> <span class="symbol">:</span> <span class="number">654.5</span> <span class="symbol">:</span> <span class="number">10.01</span> <span class="symbol">:</span> <span class="number">2.97</span></span><br><span class="line"><span class="constant">HUFFMAN </span> <span class="symbol">:</span> <span class="number">501.35</span> <span class="symbol">:</span> <span class="number">13.90</span> <span class="symbol">:</span> <span class="number">4.44</span></span><br><span class="line"><span class="constant">NEURAL NET </span> <span class="symbol">:</span> <span class="number">1.4306</span> <span class="symbol">:</span> <span class="number">2.30</span> <span class="symbol">:</span> <span class="number">0</span>.<span class="number">97</span></span><br><span class="line"><span class="constant">LU DECOMPOSITION </span> <span class="symbol">:</span> <span class="number">55.835</span> <span class="symbol">:</span> <span class="number">2.89</span> <span class="symbol">:</span> <span class="number">2.09</span></span><br><span class="line">==========================<span class="constant">ORIGINAL BYTEMARK RESULTS=</span>=========================</span><br><span class="line"><span class="constant">INTEGER INDEX </span> <span class="symbol">:</span> <span class="number">16.361</span></span><br><span class="line"><span class="constant">FLOATING-POINT INDEX:</span> <span class="number">2.151</span></span><br><span class="line"><span class="constant">Baseline </span>(<span class="constant">MSDOS*</span>) <span class="symbol">:</span> <span class="constant">Pentium*</span> <span class="number">90</span>, <span class="number">256</span> <span class="constant">KB L2-</span>cache, <span class="constant">Watcom*</span> compiler <span class="number">10.0</span></span><br><span class="line">==============================<span class="constant">LINUX DATA BELOW=</span>==============================</span><br><span class="line"><span class="constant">CPU </span> <span class="symbol">:</span></span><br><span class="line"><span class="constant">L2 Cache </span> <span class="symbol">:</span></span><br><span class="line"><span class="constant">OS </span> <span class="symbol">:</span> <span class="constant">Linux </span><span class="number">3.2</span>.<span class="number">0</span></span><br><span class="line"><span class="constant">C </span>compiler <span class="symbol">:</span> arm-arago-linux-gnueabi-gcc</span><br><span class="line">libc <span class="symbol">:</span> static</span><br><span class="line"><span class="constant">MEMORY INDEX </span> <span class="symbol">:</span> <span class="number">4.005</span></span><br><span class="line"><span class="constant">INTEGER INDEX </span> <span class="symbol">:</span> <span class="number">4.142</span></span><br><span class="line"><span class="constant">FLOATING-POINT INDEX:</span> <span class="number">1.193</span></span><br><span class="line"><span class="constant">Baseline </span>(<span class="constant">LINUX)</span> <span class="symbol">:</span> <span class="constant">AMD K6/</span><span class="number">233</span>*, <span class="number">512</span> <span class="constant">KB L2-</span>cache, gcc <span class="number">2.7</span>.<span class="number">2.3</span>, libc-<span class="number">5.4</span>.<span class="number">38</span></span><br><span class="line">* <span class="constant">Trademarks </span>are property of their respective holder.</span><br></pre></td></tr></table></figure>
<h3 id="arm-arago-linux-gnueabi-gcc_-mcpu=cortex-a8_-mfloat-abi=softfp_-mfpu=vfpv3_-O2">arm-arago-linux-gnueabi-gcc -mcpu=cortex-a8 -mfloat-abi=softfp -mfpu=vfpv3 -O2</h3><figure class="highlight elixir"><table><tr><td class="code"><pre><span class="line">root<span class="variable">@ok335x</span><span class="symbol">:/home/forlinx</span><span class="comment"># ./nbench</span></span><br><span class="line"></span><br><span class="line"><span class="constant">BYTEmark*</span> <span class="constant">Native Mode Benchmark </span>ver. <span class="number">2</span> (<span class="number">10</span>/<span class="number">95</span>)</span><br><span class="line"><span class="constant">Index-</span>split by <span class="constant">Andrew D.</span> <span class="constant">Balsa </span>(<span class="number">11</span>/<span class="number">97</span>)</span><br><span class="line"><span class="constant">Linux/Unix*</span> port by <span class="constant">Uwe F.</span> <span class="constant">Mayer </span>(<span class="number">12</span>/<span class="number">96</span>,<span class="number">11</span>/<span class="number">97</span>)</span><br><span class="line"></span><br><span class="line"><span class="constant">TEST </span> <span class="symbol">:</span> <span class="constant">Iterations/</span>sec. <span class="symbol">:</span> <span class="constant">Old Index </span> <span class="symbol">:</span> <span class="constant">New Index</span></span><br><span class="line"> <span class="symbol">:</span> <span class="symbol">:</span> <span class="constant">Pentium </span><span class="number">90</span>* <span class="symbol">:</span> <span class="constant">AMD K6/</span><span class="number">233</span>*</span><br><span class="line">--------------------<span class="symbol">:------------------</span><span class="symbol">:-------------</span><span class="symbol">:------------</span></span><br><span class="line"><span class="constant">NUMERIC SORT </span> <span class="symbol">:</span> <span class="number">356.64</span> <span class="symbol">:</span> <span class="number">9.15</span> <span class="symbol">:</span> <span class="number">3.00</span></span><br><span class="line"><span class="constant">STRING SORT </span> <span class="symbol">:</span> <span class="number">37.949</span> <span class="symbol">:</span> <span class="number">16.96</span> <span class="symbol">:</span> <span class="number">2.62</span></span><br><span class="line"><span class="constant">BITFIELD </span> <span class="symbol">:</span> <span class="number">8.5789</span>e+<span class="number">07</span> <span class="symbol">:</span> <span class="number">14.72</span> <span class="symbol">:</span> <span class="number">3.07</span></span><br><span class="line"><span class="constant">FP EMULATION </span> <span class="symbol">:</span> <span class="number">32.934</span> <span class="symbol">:</span> <span class="number">15.80</span> <span class="symbol">:</span> <span class="number">3.65</span></span><br><span class="line"><span class="constant">FOURIER </span> <span class="symbol">:</span> <span class="number">1303.5</span> <span class="symbol">:</span> <span class="number">1.48</span> <span class="symbol">:</span> <span class="number">0</span>.<span class="number">83</span></span><br><span class="line"><span class="constant">ASSIGNMENT </span> <span class="symbol">:</span> <span class="number">5.2346</span> <span class="symbol">:</span> <span class="number">19.92</span> <span class="symbol">:</span> <span class="number">5.17</span></span><br><span class="line"><span class="constant">IDEA </span> <span class="symbol">:</span> <span class="number">646.3</span> <span class="symbol">:</span> <span class="number">9.88</span> <span class="symbol">:</span> <span class="number">2.93</span></span><br><span class="line"><span class="constant">HUFFMAN </span> <span class="symbol">:</span> <span class="number">490.39</span> <span class="symbol">:</span> <span class="number">13.60</span> <span class="symbol">:</span> <span class="number">4.34</span></span><br><span class="line"><span class="constant">NEURAL NET </span> <span class="symbol">:</span> <span class="number">1.5157</span> <span class="symbol">:</span> <span class="number">2.43</span> <span class="symbol">:</span> <span class="number">1.02</span></span><br><span class="line"><span class="constant">LU DECOMPOSITION </span> <span class="symbol">:</span> <span class="number">55.698</span> <span class="symbol">:</span> <span class="number">2.89</span> <span class="symbol">:</span> <span class="number">2.08</span></span><br><span class="line">==========================<span class="constant">ORIGINAL BYTEMARK RESULTS=</span>=========================</span><br><span class="line"><span class="constant">INTEGER INDEX </span> <span class="symbol">:</span> <span class="number">13.826</span></span><br><span class="line"><span class="constant">FLOATING-POINT INDEX:</span> <span class="number">2.184</span></span><br><span class="line"><span class="constant">Baseline </span>(<span class="constant">MSDOS*</span>) <span class="symbol">:</span> <span class="constant">Pentium*</span> <span class="number">90</span>, <span class="number">256</span> <span class="constant">KB L2-</span>cache, <span class="constant">Watcom*</span> compiler <span class="number">10.0</span></span><br><span class="line">==============================<span class="constant">LINUX DATA BELOW=</span>==============================</span><br><span class="line"><span class="constant">CPU </span> <span class="symbol">:</span></span><br><span class="line"><span class="constant">L2 Cache </span> <span class="symbol">:</span></span><br><span class="line"><span class="constant">OS </span> <span class="symbol">:</span> <span class="constant">Linux </span><span class="number">3.2</span>.<span class="number">0</span></span><br><span class="line"><span class="constant">C </span>compiler <span class="symbol">:</span> arm-arago-linux-gnueabi-gcc</span><br><span class="line">libc <span class="symbol">:</span> static</span><br><span class="line"><span class="constant">MEMORY INDEX </span> <span class="symbol">:</span> <span class="number">3.467</span></span><br><span class="line"><span class="constant">INTEGER INDEX </span> <span class="symbol">:</span> <span class="number">3.437</span></span><br><span class="line"><span class="constant">FLOATING-POINT INDEX:</span> <span class="number">1.211</span></span><br><span class="line"><span class="constant">Baseline </span>(<span class="constant">LINUX)</span> <span class="symbol">:</span> <span class="constant">AMD K6/</span><span class="number">233</span>*, <span class="number">512</span> <span class="constant">KB L2-</span>cache, gcc <span class="number">2.7</span>.<span class="number">2.3</span>, libc-<span class="number">5.4</span>.<span class="number">38</span></span><br><span class="line">* <span class="constant">Trademarks </span>are property of their respective holder.</span><br></pre></td></tr></table></figure>
<h2 id="SylixOS测试结果">SylixOS测试结果</h2><h3 id="arm-sylixos-eabi-gcc_-mcpu=cortex-a8_-mfloat-abi=softfp_-mfpu=vfpv3_-O3">arm-sylixos-eabi-gcc -mcpu=cortex-a8 -mfloat-abi=softfp -mfpu=vfpv3 -O3</h3><figure class="highlight haml"><table><tr><td class="code"><pre><span class="line">[root@sylixos_station:/apps]# ./nbench</span><br><span class="line"></span><br><span class="line">BYTEmark* Native Mode Benchmark ver. 2 (10/95)</span><br><span class="line">Index-split by Andrew D. Balsa (11/97)</span><br><span class="line">Linux/Unix* port by Uwe F. Mayer (12/96,11/97)</span><br><span class="line"></span><br><span class="line">TEST : Iterations/sec. : Old Index : New Index</span><br><span class="line"> : : Pentium 90* : AMD K6/233*</span><br><span class="line">-<span class="ruby">-------------------<span class="symbol">:------------------</span><span class="symbol">:-------------</span><span class="symbol">:------------</span></span><br><span class="line"></span>NUMERIC SORT : 386.53 : 9.91 : 3.26</span><br><span class="line">STRING SORT : 12.447 : 5.56 : 0.86</span><br><span class="line">BITFIELD : 1.4006e+08 : 24.03 : 5.02</span><br><span class="line">FP EMULATION : 88.258 : 42.35 : 9.77</span><br><span class="line">FOURIER : 1591.8 : 1.81 : 1.02</span><br><span class="line">ASSIGNMENT : 6.4511 : 24.55 : 6.37</span><br><span class="line">IDEA : 958.43 : 14.66 : 4.35</span><br><span class="line">HUFFMAN : 619.13 : 17.17 : 5.48</span><br><span class="line">NEURAL NET : 1.6131 : 2.59 : 1.09</span><br><span class="line">LU DECOMPOSITION : 59.127 : 3.06 : 2.21</span><br><span class="line">=<span class="ruby">=========================<span class="constant">ORIGINAL</span> <span class="constant">BYTEMARK</span> <span class="constant">RESULTS</span>==========================</span><br><span class="line"></span>INTEGER INDEX : 16.595</span><br><span class="line">FLOATING-POINT INDEX: 2.431</span><br><span class="line">Baseline (MSDOS*) : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0</span><br><span class="line">=<span class="ruby">=============================<span class="constant">LINUX</span> <span class="constant">DATA</span> <span class="constant">BELOW</span>===============================</span><br><span class="line"></span>CPU :</span><br><span class="line">L2 Cache :</span><br><span class="line">OS : sh: command not found.</span><br><span class="line">C compiler :</span><br><span class="line">libc :</span><br><span class="line">MEMORY INDEX : 3.019</span><br><span class="line">INTEGER INDEX : 5.249</span><br><span class="line">FLOATING-POINT INDEX: 1.348</span><br><span class="line">Baseline (LINUX) : AMD K6/233*, 512 KB L2-cache, gcc 2.7.2.3, libc-5.4.38</span><br><span class="line">* Trademarks are property of their respective holder.</span><br></pre></td></tr></table></figure>
<h3 id="arm-sylixos-eabi-gcc_-mcpu=cortex-a8_-mfloat-abi=softfp_-mfpu=neon_-O3">arm-sylixos-eabi-gcc -mcpu=cortex-a8 -mfloat-abi=softfp -mfpu=neon -O3</h3><figure class="highlight haml"><table><tr><td class="code"><pre><span class="line">[root@sylixos_station:/apps]# ./nbench</span><br><span class="line"></span><br><span class="line">BYTEmark* Native Mode Benchmark ver. 2 (10/95)</span><br><span class="line">Index-split by Andrew D. Balsa (11/97)</span><br><span class="line">Linux/Unix* port by Uwe F. Mayer (12/96,11/97)</span><br><span class="line"></span><br><span class="line">TEST : Iterations/sec. : Old Index : New Index</span><br><span class="line"> : : Pentium 90* : AMD K6/233*</span><br><span class="line">-<span class="ruby">-------------------<span class="symbol">:------------------</span><span class="symbol">:-------------</span><span class="symbol">:------------</span></span><br><span class="line"></span>NUMERIC SORT : 386.79 : 9.92 : 3.26</span><br><span class="line">STRING SORT : 12.32 : 5.50 : 0.85</span><br><span class="line">BITFIELD : 1.4009e+08 : 24.03 : 5.02</span><br><span class="line">FP EMULATION : 84.482 : 40.54 : 9.35</span><br><span class="line">FOURIER : 1633.5 : 1.86 : 1.04</span><br><span class="line">ASSIGNMENT : 6.7122 : 25.54 : 6.62</span><br><span class="line">IDEA : 958.12 : 14.65 : 4.35</span><br><span class="line">HUFFMAN : 615.79 : 17.08 : 5.45</span><br><span class="line">NEURAL NET : 1.6196 : 2.60 : 1.09</span><br><span class="line">LU DECOMPOSITION : 59.124 : 3.06 : 2.21</span><br><span class="line">=<span class="ruby">=========================<span class="constant">ORIGINAL</span> <span class="constant">BYTEMARK</span> <span class="constant">RESULTS</span>==========================</span><br><span class="line"></span>INTEGER INDEX : 16.549</span><br><span class="line">FLOATING-POINT INDEX: 2.455</span><br><span class="line">Baseline (MSDOS*) : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0</span><br><span class="line">=<span class="ruby">=============================<span class="constant">LINUX</span> <span class="constant">DATA</span> <span class="constant">BELOW</span>===============================</span><br><span class="line"></span>CPU :</span><br><span class="line">L2 Cache :</span><br><span class="line">OS : sh: command not found.</span><br><span class="line">C compiler :</span><br><span class="line">libc :</span><br><span class="line">MEMORY INDEX : 3.049</span><br><span class="line">INTEGER INDEX : 5.185</span><br><span class="line">FLOATING-POINT INDEX: 1.362</span><br><span class="line">Baseline (LINUX) : AMD K6/233*, 512 KB L2-cache, gcc 2.7.2.3, libc-5.4.38</span><br><span class="line">* Trademarks are property of their respective holder.</span><br></pre></td></tr></table></figure>
<h3 id="arm-sylixos-eabi-gcc_-mcpu=cortex-a8_-O3">arm-sylixos-eabi-gcc -mcpu=cortex-a8 -O3</h3><figure class="highlight haml"><table><tr><td class="code"><pre><span class="line">[root@sylixos_station:/apps]# ./nbench</span><br><span class="line"></span><br><span class="line">BYTEmark* Native Mode Benchmark ver. 2 (10/95)</span><br><span class="line">Index-split by Andrew D. Balsa (11/97)</span><br><span class="line">Linux/Unix* port by Uwe F. Mayer (12/96,11/97)</span><br><span class="line"></span><br><span class="line">TEST : Iterations/sec. : Old Index : New Index</span><br><span class="line"> : : Pentium 90* : AMD K6/233*</span><br><span class="line">-<span class="ruby">-------------------<span class="symbol">:------------------</span><span class="symbol">:-------------</span><span class="symbol">:------------</span></span><br><span class="line"></span>NUMERIC SORT : 386.91 : 9.92 : 3.26</span><br><span class="line">STRING SORT : 12.429 : 5.55 : 0.86</span><br><span class="line">BITFIELD : 1.4009e+08 : 24.03 : 5.02</span><br><span class="line">FP EMULATION : 89.179 : 42.79 : 9.87</span><br><span class="line">FOURIER : 424.47 : 0.48 : 0.27</span><br><span class="line">ASSIGNMENT : 6.5648 : 24.98 : 6.48</span><br><span class="line">IDEA : 958.47 : 14.66 : 4.35</span><br><span class="line">HUFFMAN : 565.9 : 15.69 : 5.01</span><br><span class="line">NEURAL NET : 0.53259 : 0.86 : 0.36</span><br><span class="line">LU DECOMPOSITION : 16.094 : 0.83 : 0.60</span><br><span class="line">=<span class="ruby">=========================<span class="constant">ORIGINAL</span> <span class="constant">BYTEMARK</span> <span class="constant">RESULTS</span>==========================</span><br><span class="line"></span>INTEGER INDEX : 16.448</span><br><span class="line">FLOATING-POINT INDEX: 0.701</span><br><span class="line">Baseline (MSDOS*) : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0</span><br><span class="line">=<span class="ruby">=============================<span class="constant">LINUX</span> <span class="constant">DATA</span> <span class="constant">BELOW</span>===============================</span><br><span class="line"></span>CPU :</span><br><span class="line">L2 Cache :</span><br><span class="line">OS : sh: command not found.</span><br><span class="line">C compiler :</span><br><span class="line">libc :</span><br><span class="line">MEMORY INDEX : 3.035</span><br><span class="line">INTEGER INDEX : 5.147</span><br><span class="line">FLOATING-POINT INDEX: 0.389</span><br><span class="line">Baseline (LINUX) : AMD K6/233*, 512 KB L2-cache, gcc 2.7.2.3, libc-5.4.38</span><br><span class="line">* Trademarks are property of their respective holder.</span><br></pre></td></tr></table></figure>
<h3 id="arm-sylixos-eabi-gcc_-mcpu=arm920t_-O3">arm-sylixos-eabi-gcc -mcpu=arm920t -O3</h3><figure class="highlight haml"><table><tr><td class="code"><pre><span class="line">[root@sylixos_station:/apps]# ./nbench</span><br><span class="line"></span><br><span class="line">BYTEmark* Native Mode Benchmark ver. 2 (10/95)</span><br><span class="line">Index-split by Andrew D. Balsa (11/97)</span><br><span class="line">Linux/Unix* port by Uwe F. Mayer (12/96,11/97)</span><br><span class="line"></span><br><span class="line">TEST : Iterations/sec. : Old Index : New Index</span><br><span class="line"> : : Pentium 90* : AMD K6/233*</span><br><span class="line">-<span class="ruby">-------------------<span class="symbol">:------------------</span><span class="symbol">:-------------</span><span class="symbol">:------------</span></span><br><span class="line"></span>NUMERIC SORT : 400.44 : 10.27 : 3.37</span><br><span class="line">STRING SORT : 12.422 : 5.55 : 0.86</span><br><span class="line">BITFIELD : 1.3164e+08 : 22.58 : 4.72</span><br><span class="line">FP EMULATION : 81.987 : 39.34 : 9.08</span><br><span class="line">FOURIER : 411.76 : 0.47 : 0.26</span><br><span class="line">ASSIGNMENT : 6.3944 : 24.33 : 6.31</span><br><span class="line">IDEA : 1027.1 : 15.71 : 4.66</span><br><span class="line">HUFFMAN : 559.44 : 15.51 : 4.95</span><br><span class="line">NEURAL NET : 0.52203 : 0.84 : 0.35</span><br><span class="line">LU DECOMPOSITION : 15.716 : 0.81 : 0.59</span><br><span class="line">=<span class="ruby">=========================<span class="constant">ORIGINAL</span> <span class="constant">BYTEMARK</span> <span class="constant">RESULTS</span>==========================</span><br><span class="line"></span>INTEGER INDEX : 16.258</span><br><span class="line">FLOATING-POINT INDEX: 0.684</span><br><span class="line">Baseline (MSDOS*) : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0</span><br><span class="line">=<span class="ruby">=============================<span class="constant">LINUX</span> <span class="constant">DATA</span> <span class="constant">BELOW</span>===============================</span><br><span class="line"></span>CPU :</span><br><span class="line">L2 Cache :</span><br><span class="line">OS : sh: command not found.</span><br><span class="line">C compiler :</span><br><span class="line">libc :</span><br><span class="line">MEMORY INDEX : 2.946</span><br><span class="line">INTEGER INDEX : 5.157</span><br><span class="line">FLOATING-POINT INDEX: 0.379</span><br><span class="line">Baseline (LINUX) : AMD K6/233*, 512 KB L2-cache, gcc 2.7.2.3, libc-5.4.38</span><br><span class="line">* Trademarks are property of their respective holder.</span><br></pre></td></tr></table></figure>
<h3 id="arm-sylixos-eabi-gcc_-mcpu=cortex-a8_-mfloat-abi=softfp_-mfpu=vfpv3_-O2">arm-sylixos-eabi-gcc -mcpu=cortex-a8 -mfloat-abi=softfp -mfpu=vfpv3 -O2</h3><figure class="highlight haml"><table><tr><td class="code"><pre><span class="line">[root@sylixos_station:/apps]# ./nbench</span><br><span class="line"></span><br><span class="line">BYTEmark* Native Mode Benchmark ver. 2 (10/95)</span><br><span class="line">Index-split by Andrew D. Balsa (11/97)</span><br><span class="line">Linux/Unix* port by Uwe F. Mayer (12/96,11/97)</span><br><span class="line"></span><br><span class="line">TEST : Iterations/sec. : Old Index : New Index</span><br><span class="line"> : : Pentium 90* : AMD K6/233*</span><br><span class="line">-<span class="ruby">-------------------<span class="symbol">:------------------</span><span class="symbol">:-------------</span><span class="symbol">:------------</span></span><br><span class="line"></span>NUMERIC SORT : 335.32 : 8.60 : 2.82</span><br><span class="line">STRING SORT : 11.952 : 5.34 : 0.83</span><br><span class="line">BITFIELD : 1.4737e+08 : 25.28 : 5.28</span><br><span class="line">FP EMULATION : 55.498 : 26.63 : 6.15</span><br><span class="line">FOURIER : 1555.4 : 1.77 : 0.99</span><br><span class="line">ASSIGNMENT : 6.5063 : 24.76 : 6.42</span><br><span class="line">IDEA : 1042.9 : 15.95 : 4.74</span><br><span class="line">HUFFMAN : 612.91 : 17.00 : 5.43</span><br><span class="line">NEURAL NET : 1.5783 : 2.54 : 1.07</span><br><span class="line">LU DECOMPOSITION : 59.134 : 3.06 : 2.21</span><br><span class="line">=<span class="ruby">=========================<span class="constant">ORIGINAL</span> <span class="constant">BYTEMARK</span> <span class="constant">RESULTS</span>==========================</span><br><span class="line"></span>INTEGER INDEX : 15.422</span><br><span class="line">FLOATING-POINT INDEX: 2.395</span><br><span class="line">Baseline (MSDOS*) : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0</span><br><span class="line">=<span class="ruby">=============================<span class="constant">LINUX</span> <span class="constant">DATA</span> <span class="constant">BELOW</span>===============================</span><br><span class="line"></span>CPU :</span><br><span class="line">L2 Cache :</span><br><span class="line">OS : sh: command not found.</span><br><span class="line">C compiler :</span><br><span class="line">libc :</span><br><span class="line">MEMORY INDEX : 3.038</span><br><span class="line">INTEGER INDEX : 4.596</span><br><span class="line">FLOATING-POINT INDEX: 1.328</span><br><span class="line">Baseline (LINUX) : AMD K6/233*, 512 KB L2-cache, gcc 2.7.2.3, libc-5.4.38</span><br><span class="line">* Trademarks are property of their respective holder.</span><br></pre></td></tr></table></figure>
<h2 id="Linux_SylixOS_测试结果汇总与对比">Linux SylixOS 测试结果汇总与对比</h2><table>
<thead>
<tr>
<th>Linux AM335x</th>
<th style="text-align:left">cortex-a8 vfpv3 -O3</th>
<th style="text-align:left">cortex-a8 neon -O3</th>
<th style="text-align:left">cortex-a8 -O3</th>
<th style="text-align:left">arm920t -O3</th>
<th style="text-align:left">cortex-a8 -vfpv3 -O2</th>
</tr>
</thead>
<tbody>
<tr>
<td>MEMORY INDEX</td>
<td style="text-align:left">4.129</td>
<td style="text-align:left">3.961</td>
<td style="text-align:left">4.130</td>
<td style="text-align:left">4.005</td>
<td style="text-align:left">3.467</td>
</tr>
<tr>
<td>INTEGER INDEX</td>
<td style="text-align:left">4.565</td>
<td style="text-align:left">4.564</td>
<td style="text-align:left">4.563</td>
<td style="text-align:left">4.142</td>
<td style="text-align:left">3.437</td>
</tr>
<tr>
<td>FLOATING-POINT INDEX</td>
<td style="text-align:left">1.189</td>
<td style="text-align:left">1.185</td>
<td style="text-align:left">1.183</td>
<td style="text-align:left">1.193</td>
<td style="text-align:left">1.211</td>
</tr>
</tbody>
</table>
<p>不同 FPU 编译选项,浮点性能差异极少,怀疑 arm-arago-linux-gnueabi-gcc 默认就打开了硬件浮点。</p>
<table>
<thead>
<tr>
<th>SylixOS AM335x</th>
<th style="text-align:left">cortex-a8 vfpv3 -O3</th>
<th style="text-align:left">cortex-a8 neon -O3</th>
<th style="text-align:left">cortex-a8 -O3</th>
<th style="text-align:left">arm920t -O3</th>
<th style="text-align:left">cortex-a8 -vfpv3 -O2</th>
</tr>
</thead>
<tbody>
<tr>
<td>MEMORY INDEX</td>
<td style="text-align:left">3.019</td>
<td style="text-align:left">3.049</td>
<td style="text-align:left">3.035</td>
<td style="text-align:left">2.946</td>
<td style="text-align:left">3.038</td>
</tr>
<tr>
<td>INTEGER INDEX</td>
<td style="text-align:left">5.249</td>
<td style="text-align:left">5.185</td>
<td style="text-align:left">5.147</td>
<td style="text-align:left">5.157</td>
<td style="text-align:left">4.596</td>
</tr>
<tr>
<td>FLOATING-POINT INDEX</td>
<td style="text-align:left">1.348</td>
<td style="text-align:left">1.362</td>
<td style="text-align:left">0.389</td>
<td style="text-align:left">0.379</td>
<td style="text-align:left">1.328</td>
</tr>
</tbody>
</table>
<p>不同 FPU 编译选项,浮点性能差异较大,说明 arm-sylixos-eabi-gcc 默认不打开了硬件浮点。</p>
<p>SylixOS 的 INTEGER INDEX (定点处理性能)与 FLOATING-POINT INDEX (浮点处理性能)要优于 Linux,而 MEMORY INDEX (内存性能)要低于 Linux。</p>
<p><strong>值得注意:使用 -mfpu=neon 编译选项不见得比 -mfpu=vfpv3 要好,频繁地切换 ARM/NEON 指令集反而会使性能有所损耗。<br>在 Cortex-A8 处理器上 NEON 单元是强制的,但在 Cortex-A9 处理器上 NEON 单元却是可选的,使用 -mcpu=cortex-a8 -mfpu=vfpv3 -O3 编译选项可以获得最优化性能和兼容性。<br>当然 -O3 优化可能也会带来一些问题,如果 -O2 优化已经足够,那么建议使用 -O2 优化选项,这也是 SylixOS Release 版本使用的优化选项。</strong></p>
<h2 id="Linux_SylixOS_测试结果对比分析">Linux SylixOS 测试结果对比分析</h2><p>下面的对比分析基于 -mcpu=cortex-a8 -mfpu=vfpv3 -O3 编译选项。</p>
<p>Linux:<br><figure class="highlight groovy"><table><tr><td class="code"><pre><span class="line">NUMERIC <span class="string">SORT :</span> <span class="number">395.2</span> : <span class="number">10.14</span> : <span class="number">3.33</span></span><br><span class="line">STRING <span class="string">SORT :</span> <span class="number">40.032</span> : <span class="number">17.89</span> : <span class="number">2.77</span></span><br><span class="line"><span class="string">BITFIELD :</span> <span class="number">1.3728e+08</span> : <span class="number">23.55</span> : <span class="number">4.92</span></span><br><span class="line">FP <span class="string">EMULATION :</span> <span class="number">67.8</span> : <span class="number">32.53</span> : <span class="number">7.51</span></span><br><span class="line"><span class="string">FOURIER :</span> <span class="number">1324.1</span> : <span class="number">1.51</span> : <span class="number">0.85</span></span><br><span class="line"><span class="string">ASSIGNMENT :</span> <span class="number">5.2366</span> : <span class="number">19.93</span> : <span class="number">5.17</span></span><br><span class="line"><span class="string">IDEA :</span> <span class="number">840.3</span> : <span class="number">12.85</span> : <span class="number">3.82</span></span><br><span class="line"><span class="string">HUFFMAN :</span> <span class="number">514.44</span> : <span class="number">14.27</span> : <span class="number">4.56</span></span><br><span class="line">NEURAL <span class="string">NET :</span> <span class="number">1.42</span> : <span class="number">2.28</span> : <span class="number">0.96</span></span><br><span class="line">LU <span class="string">DECOMPOSITION :</span> <span class="number">55.316</span> : <span class="number">2.87</span> : <span class="number">2.07</span></span><br></pre></td></tr></table></figure></p>
<p>SylixOS:<br><figure class="highlight groovy"><table><tr><td class="code"><pre><span class="line">NUMERIC <span class="string">SORT :</span> <span class="number">386.53</span> : <span class="number">9.91</span> : <span class="number">3.26</span></span><br><span class="line">STRING <span class="string">SORT :</span> <span class="number">12.447</span> : <span class="number">5.56</span> : <span class="number">0.86</span></span><br><span class="line"><span class="string">BITFIELD :</span> <span class="number">1.4006e+08</span> : <span class="number">24.03</span> : <span class="number">5.02</span></span><br><span class="line">FP <span class="string">EMULATION :</span> <span class="number">88.258</span> : <span class="number">42.35</span> : <span class="number">9.77</span></span><br><span class="line"><span class="string">FOURIER :</span> <span class="number">1591.8</span> : <span class="number">1.81</span> : <span class="number">1.02</span></span><br><span class="line"><span class="string">ASSIGNMENT :</span> <span class="number">6.4511</span> : <span class="number">24.55</span> : <span class="number">6.37</span></span><br><span class="line"><span class="string">IDEA :</span> <span class="number">958.43</span> : <span class="number">14.66</span> : <span class="number">4.35</span></span><br><span class="line"><span class="string">HUFFMAN :</span> <span class="number">619.13</span> : <span class="number">17.17</span> : <span class="number">5.48</span></span><br><span class="line">NEURAL <span class="string">NET :</span> <span class="number">1.6131</span> : <span class="number">2.59</span> : <span class="number">1.09</span></span><br><span class="line">LU <span class="string">DECOMPOSITION :</span> <span class="number">59.127</span> : <span class="number">3.06</span> : <span class="number">2.21</span></span><br></pre></td></tr></table></figure></p>
<p>SylixOS 在 NUMERIC SORT 测试中小幅落后于 Linux,而 STRING SORT 测试中大幅落后于 Linux,其它测试 SylixOS 均优于 Linux。</p>
<p>MEMORY INDEX (内存性能)低于 Linux 的原故是 STRING SORT 测试中大幅落后于 Linux。</p>
<p>STRING SORT 测试是 Sorts an array of strings of arbitrary length,落后的原因可能有三:</p>
<ol>
<li>SylixOS 相关字符串函数的执行效率不高;</li>
<li>SylixOS 未能发挥 ARMv7A Cache 性能;</li>
<li>BSP 在内存控制器设置方面存在不正确的地方。</li>
</ol>
<h2 id="在_Linux_测试_SylixOS_的_lib_memcpy_函数性能">在 Linux 测试 SylixOS 的 lib_memcpy 函数性能</h2><p>通过分析 nbench 的代码,发现 nbench 调用了 memmove 函数,在 SylixOS 上该函数使用 lib_memcpy 函数实现。</p>
<p>在 Linux 上,使用 SylixOS 的 lib_memcpy 函数替换 memmove 函数,以测试 SylixOS 的 lib_memcpy 函数的性能,编译选项为: -mcpu=cortex-a8 -mfloat-abi=softfp -mfpu=vfpv3 -O3。</p>
<p>我们只需要使用 nbench 测试 NUMERIC SORT 和 STRING SORT,nbench 支持执行时指定配置文件:<br><figure class="highlight"><table><tr><td class="code"><pre><span class="line">./nbench -CCOM.DAT</span><br></pre></td></tr></table></figure></p>
<p>COM.DAT文件内容:<br><figure class="highlight ini"><table><tr><td class="code"><pre><span class="line"><span class="setting">ALLSTATS=<span class="value">F</span></span></span><br><span class="line"><span class="setting">DONUMSORT=<span class="value">T</span></span></span><br><span class="line"><span class="setting">DOSTRINGSORT=<span class="value">T</span></span></span><br><span class="line"><span class="setting">DOBITFIELD=<span class="value">F</span></span></span><br><span class="line"><span class="setting">DOEMF=<span class="value">F</span></span></span><br><span class="line"><span class="setting">DOFOUR=<span class="value">F</span></span></span><br><span class="line"><span class="setting">DOASSIGN=<span class="value">F</span></span></span><br><span class="line"><span class="setting">DOIDEA=<span class="value">F</span></span></span><br><span class="line"><span class="setting">DOHUFF=<span class="value">F</span></span></span><br><span class="line"><span class="setting">DONNET=<span class="value">F</span></span></span><br><span class="line"><span class="setting">DOLU=<span class="value">F</span></span></span><br></pre></td></tr></table></figure></p>
<p>执行后输出:<br><figure class="highlight elixir"><table><tr><td class="code"><pre><span class="line">root<span class="variable">@ok335x</span><span class="symbol">:/home/forlinx</span><span class="comment"># ./nbench -CCOM.DAT</span></span><br><span class="line"></span><br><span class="line"><span class="constant">BYTEmark*</span> <span class="constant">Native Mode Benchmark </span>ver. <span class="number">2</span> (<span class="number">10</span>/<span class="number">95</span>)</span><br><span class="line"><span class="constant">Index-</span>split by <span class="constant">Andrew D.</span> <span class="constant">Balsa </span>(<span class="number">11</span>/<span class="number">97</span>)</span><br><span class="line"><span class="constant">Linux/Unix*</span> port by <span class="constant">Uwe F.</span> <span class="constant">Mayer </span>(<span class="number">12</span>/<span class="number">96</span>,<span class="number">11</span>/<span class="number">97</span>)</span><br><span class="line"></span><br><span class="line"><span class="constant">TEST </span> <span class="symbol">:</span> <span class="constant">Iterations/</span>sec. <span class="symbol">:</span> <span class="constant">Old Index </span> <span class="symbol">:</span> <span class="constant">New Index</span></span><br><span class="line"> <span class="symbol">:</span> <span class="symbol">:</span> <span class="constant">Pentium </span><span class="number">90</span>* <span class="symbol">:</span> <span class="constant">AMD K6/</span><span class="number">233</span>*</span><br><span class="line">--------------------<span class="symbol">:------------------</span><span class="symbol">:-------------</span><span class="symbol">:------------</span></span><br><span class="line"><span class="constant">NUMERIC SORT </span> <span class="symbol">:</span> <span class="number">394.56</span> <span class="symbol">:</span> <span class="number">10.12</span> <span class="symbol">:</span> <span class="number">3.32</span></span><br><span class="line"><span class="constant">STRING SORT </span> <span class="symbol">:</span> <span class="number">9.8736</span> <span class="symbol">:</span> <span class="number">4.41</span> <span class="symbol">:</span> <span class="number">0</span>.<span class="number">68</span></span><br><span class="line">==========================<span class="constant">ORIGINAL BYTEMARK RESULTS=</span>=========================</span><br><span class="line"><span class="constant">INTEGER INDEX </span> <span class="symbol">:</span> <span class="number">1.721</span></span><br><span class="line"><span class="constant">FLOATING-POINT INDEX:</span> <span class="number">1.000</span></span><br><span class="line"><span class="constant">Baseline </span>(<span class="constant">MSDOS*</span>) <span class="symbol">:</span> <span class="constant">Pentium*</span> <span class="number">90</span>, <span class="number">256</span> <span class="constant">KB L2-</span>cache, <span class="constant">Watcom*</span> compiler <span class="number">10.0</span></span><br><span class="line">==============================<span class="constant">LINUX DATA BELOW=</span>==============================</span><br><span class="line"><span class="constant">CPU </span> <span class="symbol">:</span></span><br><span class="line"><span class="constant">L2 Cache </span> <span class="symbol">:</span></span><br><span class="line"><span class="constant">OS </span> <span class="symbol">:</span> <span class="constant">Linux </span><span class="number">3.2</span>.<span class="number">0</span></span><br><span class="line"><span class="constant">C </span>compiler <span class="symbol">:</span> arm-arago-linux-gnueabi-gcc</span><br><span class="line">libc <span class="symbol">:</span> static</span><br><span class="line"><span class="constant">MEMORY INDEX </span> <span class="symbol">:</span> <span class="number">0</span>.<span class="number">881</span></span><br><span class="line"><span class="constant">INTEGER INDEX </span> <span class="symbol">:</span> <span class="number">1.350</span></span><br><span class="line"><span class="constant">FLOATING-POINT INDEX:</span> <span class="number">1.000</span></span><br><span class="line"><span class="constant">Baseline </span>(<span class="constant">LINUX)</span> <span class="symbol">:</span> <span class="constant">AMD K6/</span><span class="number">233</span>*, <span class="number">512</span> <span class="constant">KB L2-</span>cache, gcc <span class="number">2.7</span>.<span class="number">2.3</span>, libc-<span class="number">5.4</span>.<span class="number">38</span></span><br><span class="line">* <span class="constant">Trademarks </span>are property of their respective holder.</span><br></pre></td></tr></table></figure></p>
<p>STRING SORT 测试性能评分下降严重(从 40.032 降低到 9.8736,比 SylixOS 的 12.447 还低),可见 SylixOS 的 lib_memcpy 函数在性能上远不如 Linux 的 memmove 函数。</p>
<p>同时我们可以得出如下结论:</p>
<ol>
<li>SylixOS 的 lib_memcpy 函数在性能上远不如 Linux 的 memmove 函数;</li>
<li>SylixOS 正常发挥 ARMv7A Cache 性能;</li>
<li>BSP 正确设置了内存控制器参数。</li>
</ol>
<h2 id="使用_gprof_分析_nbench">使用 gprof 分析 nbench</h2><p>我们可以使用 gprof 工具分析 nbench,得到其运行时代码性能和调用栈。</p>
<p>nbench 工程编译和链接时加入 -pg 选项,gcc 会在每一个函数入口处调用 gnu_mcount_nc 函数,gnu_mcount_nc 函数将记录该父子函数的调用次数和关系。</p>
<p>同时启动 ITIMER_PROF 定时器(频率为1000Hz)和绑定 SIGPROF 信号,SIGPROF 信号处理函数获得当前线程的 PC 值,传入 profil_count 函数,profil_count 函数对 nbench 内的函数进行有损精度的耗时统计。</p>
<p>nbench 退出时会生成 gmon.out 文件,将其上传到计算机,计算机执行 arm-sylixos-eabi-gprof,输入文件为 gmon.out 和 nbench,arm-sylixos-eabi-gprof 将生成函数耗时、调用次数、调用栈报告。</p>
<p>使用 <a href="https://pypi.python.org/pypi/gprof2dot/" target="_blank" rel="external">gprof2dot</a> 可以该报告转换为 .dot 文件,使用 dot(<a href="http://www.graphviz.org/" target="_blank" rel="external">graphviz</a> 安装目录内)可将其转换为 png 图片或 svg 矢量图。</p>
<p>执行后输出:<br><figure class="highlight haml"><table><tr><td class="code"><pre><span class="line">[root@sylixos_station:/apps]# ./nbench -CCOM.DAT</span><br><span class="line"></span><br><span class="line">BYTEmark* Native Mode Benchmark ver. 2 (10/95)</span><br><span class="line">Index-split by Andrew D. Balsa (11/97)</span><br><span class="line">Linux/Unix* port by Uwe F. Mayer (12/96,11/97)</span><br><span class="line"></span><br><span class="line">TEST : Iterations/sec. : Old Index : New Index</span><br><span class="line"> : : Pentium 90* : AMD K6/233*</span><br><span class="line">-<span class="ruby">-------------------<span class="symbol">:------------------</span><span class="symbol">:-------------</span><span class="symbol">:------------</span></span><br><span class="line"></span>NUMERIC SORT : 60.56 : 1.55 : 0.51</span><br><span class="line">STRING SORT : 3.3703 : 1.51 : 0.23</span><br><span class="line">=<span class="ruby">=========================<span class="constant">ORIGINAL</span> <span class="constant">BYTEMARK</span> <span class="constant">RESULTS</span>==========================</span><br><span class="line"></span>INTEGER INDEX : 1.129</span><br><span class="line">FLOATING-POINT INDEX: 1.000</span><br><span class="line">Baseline (MSDOS*) : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0</span><br><span class="line">=<span class="ruby">=============================<span class="constant">LINUX</span> <span class="constant">DATA</span> <span class="constant">BELOW</span>===============================</span><br><span class="line"></span>CPU :</span><br><span class="line">L2 Cache :</span><br><span class="line">OS : sh: command not found.</span><br><span class="line">C compiler :</span><br><span class="line">libc :</span><br><span class="line">MEMORY INDEX : 0.615</span><br><span class="line">INTEGER INDEX : 0.845</span><br><span class="line">FLOATING-POINT INDEX: 1.000</span><br><span class="line">Baseline (LINUX) : AMD K6/233*, 512 KB L2-cache, gcc 2.7.2.3, libc-5.4.38</span><br><span class="line">* Trademarks are property of their respective holder.</span><br><span class="line">save to libvpmpdm_gmon.out success</span><br><span class="line">save to gmon.out success</span><br></pre></td></tr></table></figure></p>
<p>这里性能参数不具参考价值,我们只关心 libvpmpdm_gmon.out 和 gmon.out。</p>
<p>libvpmpdm_gmon.out 是 libvpmpdm.so 的性能文件,gmon.out 是 nbench 的性能文件,由于 glibc 自带的 libgmon 只支持静态链接的应用程序,所以我们在移植 libgmon 到 SylixOS 时做了大量的修改,让其支持动态链接的应用程序,每一个链接库和应用程序均生成一个 gmon.out 文件。</p>
<p>libvpmpdm.so 对应的调用栈图:<br><img src="/img/使用-gprof-分析代码性能和调用栈/libvpmpdm_gprof.svg" alt="libvpmpdm_gprof.svg"></p>
<p>可以看到 libvpmpdm.so 最耗时的是 lib_memcpy 函数(44.28%)。</p>
<p>nbench 对应的调用栈图:<br><img src="/img/使用-gprof-分析代码性能和调用栈/nbench_gprof.svg" alt="nbench_gprof.svg"></p>
<p>可以看到 nbench 最耗时的是 NumSift 函数(35.05%)。</p>
<p>可以得出,如果我们想提升的 nbench 的 MEM 性能,必须优化 lib_memcpy 函数。</p>
<h2 id="lib_memcpy_函数优化">lib_memcpy 函数优化</h2><p>lib_memcpy 函数是一个编译进操作系统镜像的“内核函数”,操作系统的编译参数为 -mcpu=cortex-a8 -O2,没有使用 VFP 或 NEON 及 -O3,尝试把 lib_memcpy 函数放入在 libvpmpdm 工程,应用程序 nbench 将优先使用 libvpmpdm.so 的 lib_memcpy 函数。</p>
<p>优化最简单的方法就是修改 libvpmpdm 工程的编译选项,使用 -mcpu=cortex-a8 -mfpu=vfpv3 -O3 编译选项。</p>
<figure class="highlight haml"><table><tr><td class="code"><pre><span class="line">[root@sylixos_station:/apps]# ./nbench -CCOM.DAT</span><br><span class="line"></span><br><span class="line">BYTEmark* Native Mode Benchmark ver. 2 (10/95)</span><br><span class="line">Index-split by Andrew D. Balsa (11/97)</span><br><span class="line">Linux/Unix* port by Uwe F. Mayer (12/96,11/97)</span><br><span class="line"></span><br><span class="line">TEST : Iterations/sec. : Old Index : New Index</span><br><span class="line"> : : Pentium 90* : AMD K6/233*</span><br><span class="line">-<span class="ruby">-------------------<span class="symbol">:------------------</span><span class="symbol">:-------------</span><span class="symbol">:------------</span></span><br><span class="line"></span>NUMERIC SORT : 386.85 : 9.92 : 3.26</span><br><span class="line">STRING SORT : 11.008 : 4.92 : 0.76</span><br><span class="line">=<span class="ruby">=========================<span class="constant">ORIGINAL</span> <span class="constant">BYTEMARK</span> <span class="constant">RESULTS</span>==========================</span><br><span class="line"></span>INTEGER INDEX : 1.743</span><br><span class="line">FLOATING-POINT INDEX: 1.000</span><br><span class="line">Baseline (MSDOS*) : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0</span><br><span class="line">=<span class="ruby">=============================<span class="constant">LINUX</span> <span class="constant">DATA</span> <span class="constant">BELOW</span>===============================</span><br><span class="line"></span>CPU :</span><br><span class="line">L2 Cache :</span><br><span class="line">OS : sh: command not found.</span><br><span class="line">C compiler :</span><br><span class="line">libc :</span><br><span class="line">MEMORY INDEX : 0.913</span><br><span class="line">INTEGER INDEX : 1.344</span><br><span class="line">FLOATING-POINT INDEX: 1.000</span><br><span class="line">Baseline (LINUX) : AMD K6/233*, 512 KB L2-cache, gcc 2.7.2.3, libc-5.4.38</span><br><span class="line">* Trademarks are property of their respective holder.</span><br></pre></td></tr></table></figure>
<p>结果有点出乎意料,STRING SORT 测试性能评分不升反降,只能用其它优化方法了。</p>
<h2 id="mem_类函数移植与测试">mem 类函数移植与测试</h2><p>优化方法要么重新实现 lib_memcpy 函数,要么使用现成的 mem 类函数(memcpy、memmove等),我倾向于使用现成的 mem 类函数,</p>
<p>mem 类函数来源有以下几种:</p>
<ul>
<li>FreeBSD 的 C 库里的 mem 类函数</li>
<li>Android 的 bionic C 库里的 mem 类函数</li>
<li>编译器内建的 newlib C 库里的 mem 类函数</li>
<li>glibc C 库里的 mem 类函数</li>
</ul>
<p>以上四种 mem 类函数均使用汇编语言实现。</p>
<p>FreeBSD 的 C 库里的 mem 类函数,容易移植,但没有对 VFP 和 NEON 的优化,实测 nbench 运行到 STRING SORT 测试时直接崩溃,PASS 掉。</p>
<p>glibc C 库里的 mem 类函数过于复杂,有对 VFP 和 NEON 的优化,但不容易移植,最后才考虑。</p>
<p>编译器内建的 newlib C 库里的 mem 类函数,有对 VFP 和 NEON 的优化,不需要移植,但 SylixOS 不能使用内建的 newlib C 库,最后才考虑。</p>
<p>Android 的 bionic C 库里的 mem 类函数,有对 VFP 和 NEON 的优化,同时针对不同的 Cortex-Ax 进行优化,移植还算容易,性能应该有保证,下面尝试之。</p>
<figure class="highlight haml"><table><tr><td class="code"><pre><span class="line">[root@sylixos_station:/apps]# ./nbench -CCOM.DAT</span><br><span class="line"></span><br><span class="line">BYTEmark* Native Mode Benchmark ver. 2 (10/95)</span><br><span class="line">Index-split by Andrew D. Balsa (11/97)</span><br><span class="line">Linux/Unix* port by Uwe F. Mayer (12/96,11/97)</span><br><span class="line"></span><br><span class="line">TEST : Iterations/sec. : Old Index : New Index</span><br><span class="line"> : : Pentium 90* : AMD K6/233*</span><br><span class="line">-<span class="ruby">-------------------<span class="symbol">:------------------</span><span class="symbol">:-------------</span><span class="symbol">:------------</span></span><br><span class="line"></span>NUMERIC SORT : 386.9 : 9.92 : 3.26</span><br><span class="line">STRING SORT : 85.406 : 38.16 : 5.91</span><br><span class="line">=<span class="ruby">=========================<span class="constant">ORIGINAL</span> <span class="constant">BYTEMARK</span> <span class="constant">RESULTS</span>==========================</span><br><span class="line"></span>INTEGER INDEX : 2.335</span><br><span class="line">FLOATING-POINT INDEX: 1.000</span><br><span class="line">Baseline (MSDOS*) : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0</span><br><span class="line">=<span class="ruby">=============================<span class="constant">LINUX</span> <span class="constant">DATA</span> <span class="constant">BELOW</span>===============================</span><br><span class="line"></span>CPU :</span><br><span class="line">L2 Cache :</span><br><span class="line">OS : sh: command not found.</span><br><span class="line">C compiler :</span><br><span class="line">libc :</span><br><span class="line">MEMORY INDEX : 1.808</span><br><span class="line">INTEGER INDEX : 1.344</span><br><span class="line">FLOATING-POINT INDEX: 1.000</span><br><span class="line">Baseline (LINUX) : AMD K6/233*, 512 KB L2-cache, gcc 2.7.2.3, libc-5.4.38</span><br><span class="line">* Trademarks are property of their respective holder.</span><br></pre></td></tr></table></figure>
<p>STRING SORT 测试性能评分提升极大 (从 12.447 提升到 85.406,比 Linux 的 40.032 高出一倍多)。</p>
<p>阅读 bionic C 库里的 mem 类函数,发现其极大地发挥了 Cache 预取特性(通过 PLD 指令)。</p>
<p>将 Android 的 bionic C 库里的 mem 类函数替换掉 SylixOS 的 mem 类函数,文件主要有如下几个:<br><figure class="highlight gradle"><table><tr><td class="code"><pre><span class="line">SylixOS<span class="regexp">/lib/</span>bionic<span class="regexp">/arch-arm/</span>cortex-a15<span class="regexp">/bionic/m</span>emcpy.S \</span><br><span class="line">SylixOS<span class="regexp">/lib/</span>bionic<span class="regexp">/arch-arm/</span>cortex-a15<span class="regexp">/bionic/m</span>emset.S \</span><br><span class="line">SylixOS<span class="regexp">/lib/</span>bionic<span class="regexp">/arch-arm/</span>cortex-a15<span class="regexp">/bionic/</span>stpcpy.S \</span><br><span class="line">SylixOS<span class="regexp">/lib/</span>bionic<span class="regexp">/arch-arm/</span>cortex-a15<span class="regexp">/bionic/</span>strcat.S \</span><br><span class="line">SylixOS<span class="regexp">/lib/</span>bionic<span class="regexp">/arch-arm/</span>cortex-a15<span class="regexp">/bionic/</span>__strcat_chk.S \</span><br><span class="line">SylixOS<span class="regexp">/lib/</span>bionic<span class="regexp">/arch-arm/</span>cortex-a15<span class="regexp">/bionic/</span>strcmp.S \</span><br><span class="line">SylixOS<span class="regexp">/lib/</span>bionic<span class="regexp">/arch-arm/</span>cortex-a15<span class="regexp">/bionic/</span>strcpy.S \</span><br><span class="line">SylixOS<span class="regexp">/lib/</span>bionic<span class="regexp">/arch-arm/</span>cortex-a15<span class="regexp">/bionic/</span>__strcpy_chk.S \</span><br><span class="line">SylixOS<span class="regexp">/lib/</span>bionic<span class="regexp">/arch-arm/</span>cortex-a15<span class="regexp">/bionic/</span>strlen.S \</span><br><span class="line">SylixOS<span class="regexp">/lib/</span>bionic<span class="regexp">/arch-arm/g</span>eneric<span class="regexp">/bionic/m</span>emcmp.S \</span><br><span class="line">SylixOS<span class="regexp">/lib/</span>bionic<span class="regexp">/arch-arm/</span>denver<span class="regexp">/bionic/m</span>emmove.S \</span><br></pre></td></tr></table></figure></p>
<p>完成一次完整的测试:</p>
<figure class="highlight haml"><table><tr><td class="code"><pre><span class="line">[root@sylixos_station:/apps]# ./nbench</span><br><span class="line"></span><br><span class="line">BYTEmark* Native Mode Benchmark ver. 2 (10/95)</span><br><span class="line">Index-split by Andrew D. Balsa (11/97)</span><br><span class="line">Linux/Unix* port by Uwe F. Mayer (12/96,11/97)</span><br><span class="line"></span><br><span class="line">TEST : Iterations/sec. : Old Index : New Index</span><br><span class="line"> : : Pentium 90* : AMD K6/233*</span><br><span class="line">-<span class="ruby">-------------------<span class="symbol">:------------------</span><span class="symbol">:-------------</span><span class="symbol">:------------</span></span><br><span class="line"></span>NUMERIC SORT : 386.91 : 9.92 : 3.26</span><br><span class="line">STRING SORT : 85.585 : 38.24 : 5.92</span><br><span class="line">BITFIELD : 1.4014e+08 : 24.04 : 5.02</span><br><span class="line">FP EMULATION : 88.262 : 42.35 : 9.77</span><br><span class="line">FOURIER : 1591.9 : 1.81 : 1.02</span><br><span class="line">ASSIGNMENT : 6.5071 : 24.76 : 6.42</span><br><span class="line">IDEA : 958.89 : 14.67 : 4.35</span><br><span class="line">HUFFMAN : 620.88 : 17.22 : 5.50</span><br><span class="line">NEURAL NET : 1.6134 : 2.59 : 1.09</span><br><span class="line">LU DECOMPOSITION : 59.122 : 3.06 : 2.21</span><br><span class="line">=<span class="ruby">=========================<span class="constant">ORIGINAL</span> <span class="constant">BYTEMARK</span> <span class="constant">RESULTS</span>==========================</span><br><span class="line"></span>INTEGER INDEX : 21.899</span><br><span class="line">FLOATING-POINT INDEX: 2.431</span><br><span class="line">Baseline (MSDOS*) : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0</span><br><span class="line">=<span class="ruby">=============================<span class="constant">LINUX</span> <span class="constant">DATA</span> <span class="constant">BELOW</span>===============================</span><br><span class="line"></span>CPU :</span><br><span class="line">L2 Cache :</span><br><span class="line">OS : sh: command not found.</span><br><span class="line">C compiler :</span><br><span class="line">libc :</span><br><span class="line">MEMORY INDEX : 5.758</span><br><span class="line">INTEGER INDEX : 5.255</span><br><span class="line">FLOATING-POINT INDEX: 1.348</span><br><span class="line">Baseline (LINUX) : AMD K6/233*, 512 KB L2-cache, gcc 2.7.2.3, libc-5.4.38</span><br><span class="line">* Trademarks are property of their respective holder.</span><br></pre></td></tr></table></figure>
<h2 id="Linux_SylixOS_测试结果汇总与对比-1">Linux SylixOS 测试结果汇总与对比</h2><table>
<thead>
<tr>
<th>AM335x</th>
<th style="text-align:left">Linux cortex-a8 vfpv3 -O3</th>
<th style="text-align:left">优化前 SylixOS cortex-a8 vfpv3 -O3</th>
<th style="text-align:left">优化后 SylixOS cortex-a8 neon -O3</th>
</tr>
</thead>
<tbody>
<tr>
<td>MEMORY INDEX</td>
<td style="text-align:left">4.129</td>
<td style="text-align:left">3.019</td>
<td style="text-align:left">5.758</td>
</tr>
<tr>
<td>INTEGER INDEX</td>
<td style="text-align:left">4.565</td>
<td style="text-align:left">5.249</td>
<td style="text-align:left">5.255</td>
</tr>
<tr>
<td>FLOATING-POINT INDEX</td>
<td style="text-align:left">1.189</td>
<td style="text-align:left">1.348</td>
<td style="text-align:left">1.348</td>
</tr>
</tbody>
</table>
<p>SylixOS 的 INTEGER INDEX (定点处理性能)与 FLOATING-POINT INDEX (浮点处理性能)及 MEMORY INDEX (内存性能)均要优于 Linux。</p>
<p>SylixOS 优化前后 INTEGER INDEX 和 FLOATING-POINT INDEX 性能基本没有发生变化,但 MEMORY INDEX 性能提升较大(接近一倍的性能提升)。</p>
<h2 id="测试结论">测试结论</h2><ol>
<li>优化后的 mem 类函数的性能比 Linux 的要好;</li>
<li>SylixOS 正常发挥 ARMv7A Cache、VFP、NEON、分支预测性能,比 Linux 的还要好;</li>
<li>BSP 正确设置了内存控制器参数和处理器主频。</li>
<li>SylixOS 使用的编译器(4.9.4)比 Linux 使用的编译器(4.5.3)更能发挥 ARMv7A 性能。</li>
</ol>
]]></content>
<summary type="html">
<![CDATA[<h2 id="测试目的">测试目的</h2><p>验证 SylixOS 是否发挥 ARMv7A Cache、VFP、NEON、分支预测性能,验证 BSP 是否在内存控制器、CPU 主频设置方面存在不正确的地方。</p>
<p>找出 SylixOS 实时性远优于 Linux 和 ]]>
</summary>
<category term="SylixOS" scheme="jiaojinxing.github.io/tags/SylixOS/"/>
<category term="测试" scheme="jiaojinxing.github.io/tags/%E6%B5%8B%E8%AF%95/"/>
<category term="SylixOS" scheme="jiaojinxing.github.io/categories/SylixOS/"/>
</entry>
<entry>
<title><![CDATA[SylixOS C 库、数学库性能测试]]></title>
<link href="jiaojinxing.github.io/2015/07/17/SylixOS-C-%E5%BA%93%E3%80%81%E6%95%B0%E5%AD%A6%E5%BA%93%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95/"/>
<id>jiaojinxing.github.io/2015/07/17/SylixOS-C-库、数学库性能测试/</id>
<published>2015-07-17T13:19:24.000Z</published>
<updated>2015-07-29T13:03:54.314Z</updated>
<content type="html"><![CDATA[<h2 id="测试目的">测试目的</h2><p>验证 SylixOS 的 C 库和数学库的某些函数是否存在性能问题。</p>
<p>找出 SylixOS 实时性远优于 Linux 和 Linux+RT(见《SylixOS实时性测评报告》,和 SylixOS 在 ARMv7A 性能优于 Linux (见<a href="http://jiaojinxing.github.io/2015/07/17/SylixOS-ARMv7A-%E5%A4%84%E7%90%86%E5%99%A8%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95%E4%B8%8E%E6%94%B9%E8%BF%9B/">《SylixOS ARMv7A 处理器性能测试与改进》</a>),但 Qt 性能测试 <a href="https://github.com/jiaojinxing/qtperf" target="_blank" rel="external">qtperf</a> 中部分项目不如 Linux 的原因,并提出解决办法。</p>
<h2 id="测试环境">测试环境</h2><h3 id="硬件平台">硬件平台</h3><p>硬件平台:飞凌嵌入式 OK335xS</p>
<p>处理器:AM335x(Cortex-A8, 800MHz)</p>
<p>L1-Cache:32KB I-Cache/32KB D-Cache</p>
<p>L2-Cache:256KB</p>
<p>内存:512MB</p>
<h3 id="操作系统">操作系统</h3><p>SylixOS + bspam335x + 按《SylixOS ARMv7A 处理器性能测试与改进》一文优化后的进程补丁 libvpmpdm:2015/7/15 </p>
<p>对比测试操作系统 Linux:3.2.0(厂家配套的)</p>
<h3 id="编译器">编译器</h3><p>Linux:</p>
<p>arm-arago-linux-gnueabi-gcc: gcc version 4.5.3 20110311 (prerelease) (GCC) </p>
<p>SylixOS:</p>
<p>arm-sylixos-eabi-gcc: gcc version 4.9.3 20150303 (release) [ARM/embedded-4_9-branch revision 221220] (<br>SylixOS Toolchain for ARM Embedded Processors) </p>
<h2 id="测试软件">测试软件</h2><p>测试软件使用 glibc-2.21 中的 benchtests 程序。</p>
<p>benchtests 有如下三个方面的测试:</p>
<ol>
<li>字符串类函数性能测试</li>
<li>多线程 malloc 函数性能测试</li>
<li>数学类函数性能测试</li>
</ol>
<p>benchtests 覆盖测试了常用的 C 库和数学库函数。</p>
<p>由于厂家配套的 Linux 使用的 glibc 的版本为 2.12.2(不是 2.21),及 SylixOS 使用的是自已的实现 C 库,所以需要移植 benchtests,屏蔽了若干个 glibc-2.12.2 和 SylixOS 不支持的函数的测试。</p>
<p>benchtests 的编译选项统一使用 -mcpu=cortex-a8 -mfloat-abi=softfp -mfpu=vfpv3 -O2,由于 Linux 的文件系统已经放置了 C 库和数学库的动态库,为了避免使用这些可能不是 VFP 的动态库,所以 Linux 的 benchtests 使用静态链接(加入 -static 选项)。</p>
<p>移植好的 benchtests 放在 <a href="https://github.com/jiaojinxing/benchtest" target="_blank" rel="external">https://github.com/jiaojinxing/benchtest</a></p>
<h2 id="测试结果">测试结果</h2><p>Linux 性能测试结果放在 <a href="https://github.com/jiaojinxing/benchtests/tree/master/linux" target="_blank" rel="external">https://github.com/jiaojinxing/benchtests/tree/master/linux</a></p>
<p>SylixOS 性能测试结果放在 <a href="https://github.com/jiaojinxing/benchtests/tree/master/sylixos" target="_blank" rel="external">https://github.com/jiaojinxing/benchtests/tree/master/sylixos</a></p>
<h2 id="测试结果对比">测试结果对比</h2><p>Linux 与 SylixOS 字符串类函数性能测试结果对比放在 <a href="https://github.com/jiaojinxing/benchtests/tree/master/images" target="_blank" rel="external">https://github.com/jiaojinxing/benchtests/tree/master/images</a></p>
<p>字符串类函数性能测试结果显示,SylixOS 和 Linux 各有千秋,我们将根据这个结果,对 SylixOS 的 C 库进行优化。</p>
<p>从完成数学类函数性能测试所耗时来看,SylixOS 远优化于 Linux,本质是 newlib 的 libm 的性能比 glibc 的 libm 的性能要好得多。</p>
<p>从完成多线程 malloc 函数性能测试所耗时来看,Linux 要优于 SylixOS,本质是 Linux 的 glibc 使用的内存分配算法要优化于 SylixOS 使用的,我们将使用更优秀的内存分配算法和更精细、快速的内存分配锁。</p>
<h2 id="SylixOS_的_C_库优化">SylixOS 的 C 库优化</h2><p>根据 Linux 与 SylixOS 字符串类函数性能测试结果对比,找出 SylixOS 中有性能缺陷的字符串类函数,从 glibc-2.21 或 Android 的 bionic C 库中提取并替换原有的。</p>
<h2 id="SylixOS_内存分配算法优化">SylixOS 内存分配算法优化</h2><p>这篇文章做了一个常用内存分配算法的对比: <a href="http://webkit.sed.hu/blog/20100324/war-allocators-tlsf-action" target="_blank" rel="external">http://webkit.sed.hu/blog/20100324/war-allocators-tlsf-action</a></p>
<p>常用内存分配算法有:</p>
<ol>
<li>ptmalloc</li>
<li>tcmalloc</li>
<li>dlmalloc</li>
<li>jemalloc</li>
<li>hoard</li>
<li>tlsf</li>
<li>nedmalloc</li>
</ol>
<p><a href="http://g.oswego.edu/dl/" target="_blank" rel="external">dlmalloc</a> 由 Doug Lea 在 1987 年开发完成,这是 Android 系统中使用的内存分配器。dlmalloc 使用单 C 文件实现,约 5000 行,可移植性比较好。</p>
<p><a href="http://www.malloc.de/" target="_blank" rel="external">ptmalloc</a> 在 dlmalloc 早期的基础上进行了改进,以更好地适应多线程和 SMP,这是 Linux 系统的 glibc 中使用的内存分配器。ptmalloc 与 glibc 绑定比较紧,可移植性比较差。</p>
<p><a href="http://www.nedprod.com/programs/portable/nedmalloc/" target="_blank" rel="external">nedmalloc</a> 在 dlmalloc 的基础上加入线程 cache,实现了大多数情况下的无锁内存分配。nedmalloc 使用单 C 文件实现,约 7000 行,可移植性比较好。</p>
<p><a href="https://github.com/gperftools" target="_blank" rel="external">tcmalloc</a> 是 google 开发并开源出来的一款专为高并发而优化的内存分配器。tcmalloc 的 tc 含义是 thread cache,tcmalloc 正是通过 thread cache 这种机制实现了大多数情况下的无锁内存分配。tcmalloc 属于 google-perftools 性能分析工具中的一元,使用 C++ 实现,源代码有点多,可移植性一般。</p>
<p><a href="http://tlsf.baisoku.org/" target="_blank" rel="external">tlsf</a> (Two Level Segregated Fit)优势是用两个位图优化合适内存的查找,实现时间复杂度为常数的内存分配,非常适合在实时系统中使用。使用单 C 文件实现,约 1000 行,可移植性非常好。tlsf 的不足之处在于在 32 位机器上,malloc 返回的指针是 4 字节对齐,而非 8 字节对齐。</p>
<p><a href="http://www.canonware.com/jemalloc/" target="_blank" rel="external">jemalloc</a> 是 Jason Evans (FreeBSD 很有名的开发人员)在 2006 年为提高低性能的 malloc 而写的内存分配器。核心算法和 tcmalloc 类似,但 jemalloc 针对多核多线程进行了优化,在多核上的性能表现应该会 tcmalloc 更好。jemalloc 使用 C 实现,源代码有点多,可移植性一般。</p>
<p>将 dlmalloc、nedmalloc、tlsf、jemalloc 移植到 SylixOS 的进程补丁 libvpmpdm.so 上。</p>
<p>tlsf 并没有规定使用那种锁机制,可以使用自旋锁 spinlock 或互斥锁 mutex。</p>
<p>dlmalloc 和 nedmalloc 可以使用自旋锁 spinlock 或互斥锁 mutex。</p>
<p>jemalloc 使用互斥锁 mutex。</p>
<p>实测(客户的应用程序和 qtperf)四种内存分配算法速度性能表现如下:</p>
<p>dlmalloc(spinlock) > tlsf(spinlock) > tlsf(mutex) > dlmalloc(mutex) > nedmalloc(spinlock) > nedmalloc(mutex) > jemalloc > SylixOS 原生内存分配算法</p>
<p>所以将使用 dlmalloc(spinlock) 内存分配算法完成后续测试。</p>
]]></content>
<summary type="html">
<![CDATA[<h2 id="测试目的">测试目的</h2><p>验证 SylixOS 的 C 库和数学库的某些函数是否存在性能问题。</p>
<p>找出 SylixOS 实时性远优于 Linux 和 Linux+RT(见《SylixOS实时性测评报告》,和 SylixOS 在 ARMv7A ]]>
</summary>
<category term="SylixOS" scheme="jiaojinxing.github.io/tags/SylixOS/"/>
<category term="测试" scheme="jiaojinxing.github.io/tags/%E6%B5%8B%E8%AF%95/"/>
<category term="SylixOS" scheme="jiaojinxing.github.io/categories/SylixOS/"/>
</entry>
<entry>
<title><![CDATA[SylixOS Qt 图形界面性能测试]]></title>
<link href="jiaojinxing.github.io/2015/07/17/SylixOS-Qt-%E5%9B%BE%E5%BD%A2%E7%95%8C%E9%9D%A2%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95/"/>
<id>jiaojinxing.github.io/2015/07/17/SylixOS-Qt-图形界面性能测试/</id>
<published>2015-07-17T13:18:29.000Z</published>
<updated>2015-07-22T07:37:40.574Z</updated>
<content type="html"><![CDATA[<h2 id="测试目的">测试目的</h2><p>测试 SylixOS 上 Qt 的性能。</p>
<h2 id="测试环境">测试环境</h2><h3 id="硬件平台">硬件平台</h3><p>硬件平台:飞凌嵌入式 OK335xS</p>
<p>处理器:AM335x(Cortex-A8, 800MHz)</p>
<p>L1-Cache:32KB I-Cache/32KB D-Cache</p>
<p>L2-Cache:256KB</p>
<p>内存:512MB</p>
<h3 id="操作系统">操作系统</h3><p>SylixOS + bspam335x + 按《SylixOS ARMv7A 处理器性能测试与改进》和《SylixOS C 库、数学库性能测试》两文优化后的进程补丁 libvpmpdm:2015/7/20 </p>
<p>对比测试操作系统 Linux:3.2.0(厂家配套的)</p>
<h3 id="编译器">编译器</h3><p>Linux:</p>
<p>arm-arago-linux-gnueabi-gcc: gcc version 4.5.3 20110311 (prerelease) (GCC)(厂家配套的)</p>
<p>SylixOS:</p>
<p>arm-sylixos-eabi-gcc: gcc version 4.9.3 20150303 (release) [ARM/embedded-4_9-branch revision 221220] (<br>SylixOS Toolchain for ARM Embedded Processors) </p>
<h3 id="Qt_库">Qt 库</h3><p>Linux:</p>
<p>Qt-4.8.5(厂家配套的),编译选项:默认的 cpu 和 arch + -O2</p>
<p>SylixOS:</p>
<ol>
<li>arm-sylixos-qt-4.8.6 编译选项: -march=armv4 -mno-unaligned-access -O2</li>
<li>armv7-sylixos-qt-4.8.6 编译选项: -march=armv7-a -mfloat-abi=softfp -mfpu=neon -mno-unaligned-access -O2</li>
</ol>
<h2 id="测试软件">测试软件</h2><p>测试软件使用 <a href="https://github.com/jiaojinxing/qtperf" target="_blank" rel="external">qtperf</a> 程序。</p>
<p>使用 Qt-Creator 编译 Release 版本的 qtperf 并部署到目标板的文件系统里。</p>
<h2 id="Linux_测试结果">Linux 测试结果</h2><p>qtperf 编译选项:<br><figure class="highlight nix"><table><tr><td class="code"><pre><span class="line"><span class="variable">-mcpu=</span>cortex-a8 <span class="variable">-mfloat-abi=</span>softfp <span class="variable">-mfpu=</span>vfpv3 -O2</span><br></pre></td></tr></table></figure></p>
<figure class="highlight elixir"><table><tr><td class="code"><pre><span class="line">root<span class="variable">@ok335x</span><span class="symbol">:/home/forlinx/qtperf</span><span class="comment"># ./qtperf4 -qws &</span></span><br><span class="line">[<span class="number">1</span>] <span class="number">1545</span></span><br><span class="line">root<span class="variable">@ok335x</span><span class="symbol">:/home/forlinx/qtperf</span><span class="comment"># QLineEdit - 0.755 s</span></span><br><span class="line"><span class="constant">QComboBox </span>- <span class="number">4.08</span> s</span><br><span class="line"><span class="constant">QComboBoxEntry </span>- <span class="number">4.397</span> s</span><br><span class="line"><span class="constant">QSpinBox </span>- <span class="number">0</span>.<span class="number">472</span> s</span><br><span class="line"><span class="constant">QProgressBar </span>- <span class="number">0</span>.<span class="number">754</span> s</span><br><span class="line"><span class="constant">QPushButton </span>- <span class="number">0</span>.<span class="number">333</span> s</span><br><span class="line"><span class="constant">QCheckbox </span>- <span class="number">0</span>.<span class="number">218</span> s</span><br><span class="line"><span class="constant">QRadioButton </span>- <span class="number">0</span>.<span class="number">564</span> s</span><br><span class="line"><span class="constant">QTextEdit </span>add text - <span class="number">2.98</span> s</span><br><span class="line"><span class="constant">QTextEdit </span>scroll - <span class="number">0</span>.<span class="number">462</span> s</span><br><span class="line"><span class="constant">QPainter </span>lines - <span class="number">5.997</span> s</span><br><span class="line"><span class="constant">QPainter </span>circles - <span class="number">5.947</span> s</span><br><span class="line"><span class="constant">QPainter </span>text - <span class="number">6.363</span> s</span><br><span class="line"><span class="constant">QPainter </span>pixmap - <span class="number">6.224</span> s</span><br><span class="line"><span class="constant">Total:</span> <span class="number">39.546001</span> s</span><br></pre></td></tr></table></figure>
<h2 id="SylixOS测试结果">SylixOS测试结果</h2><h3 id="arm-sylixos-qt-4-8-6">arm-sylixos-qt-4.8.6</h3><p>qtperf 编译选项:<br><figure class="highlight armasm"><table><tr><td class="code"><pre><span class="line">-<span class="keyword">march=armv4 </span>-mno-unaligned-access -O2</span><br></pre></td></tr></table></figure></p>
<figure class="highlight stata"><table><tr><td class="code"><pre><span class="line">[root@sylixos_station:/apps/qtperf]# ./qtperf4 -qws &</span><br><span class="line">[root@sylixos_station:/apps/qtperf]# Connected to SylixOS FrameBuffer server: 800 x 480 x 32 282x169mm (72x72dpi)</span><br><span class="line">Corrupt calibration data</span><br><span class="line">QSylixOSInputMouseHandler: connected.</span><br><span class="line">QSylixOSInputKeyboardHandler: connected.</span><br><span class="line">QLineEdit - 0.943 <span class="literal">s</span></span><br><span class="line">QComboBox - 5.179 <span class="literal">s</span></span><br><span class="line">QComboBoxEntry - 5.723 <span class="literal">s</span></span><br><span class="line">QSpinBox - 0.649 <span class="literal">s</span></span><br><span class="line">QProgressBar - 0.955 <span class="literal">s</span></span><br><span class="line">QPushButton - 0.418 <span class="literal">s</span></span><br><span class="line">QCheckbox - 0.313 <span class="literal">s</span></span><br><span class="line">QRadioButton - 0.781 <span class="literal">s</span></span><br><span class="line">QTextEdit add text - 2.871 <span class="literal">s</span></span><br><span class="line">QTextEdit scroll - 0.482 <span class="literal">s</span></span><br><span class="line">QPainter lines - 4.633 <span class="literal">s</span></span><br><span class="line">QPainter circles - 4.598 <span class="literal">s</span></span><br><span class="line">QPainter text - 5.089 <span class="literal">s</span></span><br><span class="line">QPainter pixmap - 4.677 <span class="literal">s</span></span><br><span class="line"><span class="keyword">Total</span>: 37.310997 <span class="literal">s</span></span><br></pre></td></tr></table></figure>
<h3 id="armv7-sylixos-qt-4-8-6">armv7-sylixos-qt-4.8.6</h3><p>qtperf 编译选项:<br><figure class="highlight nix"><table><tr><td class="code"><pre><span class="line"><span class="variable">-march=</span>armv7-a <span class="variable">-mfloat-abi=</span>softfp <span class="variable">-mfpu=</span>neon -mno-unaligned-access -O2</span><br></pre></td></tr></table></figure></p>
<figure class="highlight stata"><table><tr><td class="code"><pre><span class="line">[root@sylixos_station:/apps/qtperf]# ./qtperf4 -qws &</span><br><span class="line">[root@sylixos_station:/apps/qtperf]# Connected to SylixOS FrameBuffer server: 80 0 x 480 x 32 282x169mm (72x72dpi)</span><br><span class="line">Corrupt calibration data</span><br><span class="line">QSylixOSInputMouseHandler: connected.</span><br><span class="line">QSylixOSInputKeyboardHandler: connected.</span><br><span class="line">QLineEdit - 0.612 <span class="literal">s</span></span><br><span class="line">QComboBox - 3.506 <span class="literal">s</span></span><br><span class="line">QComboBoxEntry - 3.726 <span class="literal">s</span></span><br><span class="line">QSpinBox - 0.367 <span class="literal">s</span></span><br><span class="line">QProgressBar - 0.568 <span class="literal">s</span></span><br><span class="line">QPushButton - 0.258 <span class="literal">s</span></span><br><span class="line">QCheckbox - 0.185 <span class="literal">s</span></span><br><span class="line">QRadioButton - 0.484 <span class="literal">s</span></span><br><span class="line">QTextEdit add text - 2.434 <span class="literal">s</span></span><br><span class="line">QTextEdit scroll - 0.317 <span class="literal">s</span></span><br><span class="line">QPainter lines - 4.325 <span class="literal">s</span></span><br><span class="line">QPainter circles - 4.279 <span class="literal">s</span></span><br><span class="line">QPainter text - 4.7 <span class="literal">s</span></span><br><span class="line">QPainter pixmap - 4.301 <span class="literal">s</span></span><br><span class="line"><span class="keyword">Total</span>: 30.062002 <span class="literal">s</span></span><br></pre></td></tr></table></figure>
<h2 id="测试结果汇总与对比">测试结果汇总与对比</h2><p>测试结果汇总如下表:</p>
<table>
<thead>
<tr>
<th>AM335x</th>
<th style="text-align:left">Linux Qt-4.8.5</th>
<th style="text-align:left">arm-sylixos-qt-4.8.6</th>
<th style="text-align:left">armv7-sylixos-qt-4.8.6</th>
</tr>
</thead>
<tbody>
<tr>
<td>QLineEdit</td>
<td style="text-align:left">0.755 s</td>
<td style="text-align:left">0.943 s</td>
<td style="text-align:left">0.612 s</td>
</tr>
<tr>
<td>QComboBox</td>
<td style="text-align:left">4.08 s</td>
<td style="text-align:left">5.179 s</td>
<td style="text-align:left">3.506 s</td>
</tr>
<tr>
<td>QComboBoxEntry</td>
<td style="text-align:left">4.397 s</td>
<td style="text-align:left">5.723 s</td>
<td style="text-align:left">3.726 s</td>
</tr>
<tr>
<td>QSpinBox</td>
<td style="text-align:left">0.472 s</td>
<td style="text-align:left">0.649 s</td>
<td style="text-align:left">0.367 s</td>
</tr>
<tr>
<td>QProgressBar</td>
<td style="text-align:left">0.754 s</td>
<td style="text-align:left">0.955 s</td>
<td style="text-align:left">0.568 s</td>
</tr>
<tr>
<td>QPushButton</td>
<td style="text-align:left">0.333 s</td>
<td style="text-align:left">0.418 s</td>
<td style="text-align:left">0.258 s</td>
</tr>
<tr>
<td>QCheckbox</td>
<td style="text-align:left">0.218 s</td>
<td style="text-align:left">0.313 s</td>
<td style="text-align:left">0.185 s</td>
</tr>
<tr>
<td>QRadioButton</td>
<td style="text-align:left">0.564 s</td>
<td style="text-align:left">0.781 s</td>
<td style="text-align:left">0.484 s</td>
</tr>
<tr>
<td>QTextEdit add text</td>
<td style="text-align:left">2.98 s</td>
<td style="text-align:left">2.871 s</td>
<td style="text-align:left">2.434 s</td>
</tr>
<tr>
<td>QTextEdit scroll</td>
<td style="text-align:left">0.462 s</td>
<td style="text-align:left">0.482 s</td>
<td style="text-align:left">0.317 s</td>
</tr>
<tr>
<td>QPainter lines</td>
<td style="text-align:left">5.997 s</td>
<td style="text-align:left">4.633 s</td>
<td style="text-align:left">4.325 s</td>
</tr>
<tr>
<td>QPainter circles</td>
<td style="text-align:left">5.947 s</td>
<td style="text-align:left">4.598 s</td>
<td style="text-align:left">4.279 s</td>
</tr>
<tr>
<td>QPainter text</td>
<td style="text-align:left">6.363 s</td>
<td style="text-align:left">5.089 s</td>
<td style="text-align:left">4.7 s</td>
</tr>
<tr>
<td>QPainter pixmap</td>
<td style="text-align:left">6.224 s</td>
<td style="text-align:left">4.677 s</td>