- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在answer中,我已经说过,未对齐的访问与长时间(在x86/x86_64上)的对齐访问的速度几乎相同。我没有任何数字可以支持此声明,因此我为此创建了一个基准。
在此基准测试中,您是否看到任何缺陷?您是否可以对此进行改进(我的意思是增加GB/秒,以便更好地反射(reflect)真相)?
#include <sys/time.h>
#include <stdio.h>
template <int N>
__attribute__((noinline))
void loop32(const char *v) {
for (int i=0; i<N; i+=160) {
__asm__ ("mov (%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x04(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x08(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x0c(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x10(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x14(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x18(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x1c(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x20(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x24(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x28(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x2c(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x30(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x34(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x38(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x3c(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x40(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x44(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x48(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x4c(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x50(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x54(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x58(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x5c(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x60(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x64(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x68(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x6c(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x70(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x74(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x78(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x7c(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x80(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x84(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x88(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x8c(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x90(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x94(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x98(%0), %%eax" : : "r"(v) :"eax");
__asm__ ("mov 0x9c(%0), %%eax" : : "r"(v) :"eax");
v += 160;
}
}
template <int N>
__attribute__((noinline))
void loop64(const char *v) {
for (int i=0; i<N; i+=160) {
__asm__ ("mov (%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x08(%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x10(%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x18(%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x20(%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x28(%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x30(%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x38(%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x40(%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x48(%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x50(%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x58(%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x60(%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x68(%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x70(%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x78(%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x80(%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x88(%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x90(%0), %%rax" : : "r"(v) :"rax");
__asm__ ("mov 0x98(%0), %%rax" : : "r"(v) :"rax");
v += 160;
}
}
template <int N>
__attribute__((noinline))
void loop128a(const char *v) {
for (int i=0; i<N; i+=160) {
__asm__ ("movaps (%0), %%xmm0" : : "r"(v) :"xmm0");
__asm__ ("movaps 0x10(%0), %%xmm0" : : "r"(v) :"xmm0");
__asm__ ("movaps 0x20(%0), %%xmm0" : : "r"(v) :"xmm0");
__asm__ ("movaps 0x30(%0), %%xmm0" : : "r"(v) :"xmm0");
__asm__ ("movaps 0x40(%0), %%xmm0" : : "r"(v) :"xmm0");
__asm__ ("movaps 0x50(%0), %%xmm0" : : "r"(v) :"xmm0");
__asm__ ("movaps 0x60(%0), %%xmm0" : : "r"(v) :"xmm0");
__asm__ ("movaps 0x70(%0), %%xmm0" : : "r"(v) :"xmm0");
__asm__ ("movaps 0x80(%0), %%xmm0" : : "r"(v) :"xmm0");
__asm__ ("movaps 0x90(%0), %%xmm0" : : "r"(v) :"xmm0");
v += 160;
}
}
template <int N>
__attribute__((noinline))
void loop128u(const char *v) {
for (int i=0; i<N; i+=160) {
__asm__ ("movups (%0), %%xmm0" : : "r"(v) :"xmm0");
__asm__ ("movups 0x10(%0), %%xmm0" : : "r"(v) :"xmm0");
__asm__ ("movups 0x20(%0), %%xmm0" : : "r"(v) :"xmm0");
__asm__ ("movups 0x30(%0), %%xmm0" : : "r"(v) :"xmm0");
__asm__ ("movups 0x40(%0), %%xmm0" : : "r"(v) :"xmm0");
__asm__ ("movups 0x50(%0), %%xmm0" : : "r"(v) :"xmm0");
__asm__ ("movups 0x60(%0), %%xmm0" : : "r"(v) :"xmm0");
__asm__ ("movups 0x70(%0), %%xmm0" : : "r"(v) :"xmm0");
__asm__ ("movups 0x80(%0), %%xmm0" : : "r"(v) :"xmm0");
__asm__ ("movups 0x90(%0), %%xmm0" : : "r"(v) :"xmm0");
v += 160;
}
}
long long int t() {
struct timeval tv;
gettimeofday(&tv, 0);
return (long long int)tv.tv_sec*1000000 + tv.tv_usec;
}
int main() {
const int ITER = 10;
const int N = 1600000000;
char *data = reinterpret_cast<char *>(((reinterpret_cast<unsigned long long>(new char[N+32])+15)&~15));
for (int i=0; i<N+16; i++) data[i] = 0;
{
long long int t0 = t();
for (int i=0; i<ITER*100000; i++) {
loop32<N/100000>(data);
}
long long int t1 = t();
for (int i=0; i<ITER*100000; i++) {
loop32<N/100000>(data+1);
}
long long int t2 = t();
for (int i=0; i<ITER; i++) {
loop32<N>(data);
}
long long int t3 = t();
for (int i=0; i<ITER; i++) {
loop32<N>(data+1);
}
long long int t4 = t();
printf(" 32-bit, cache: aligned: %8.4f GB/sec unaligned: %8.4f GB/sec, difference: %0.3f%%\n", (double)N*ITER/(t1-t0)/1000, (double)N*ITER/(t2-t1)/1000, 100.0*(t2-t1)/(t1-t0)-100.0f);
printf(" 32-bit, mem: aligned: %8.4f GB/sec unaligned: %8.4f GB/sec, difference: %0.3f%%\n", (double)N*ITER/(t3-t2)/1000, (double)N*ITER/(t4-t3)/1000, 100.0*(t4-t3)/(t3-t2)-100.0f);
}
{
long long int t0 = t();
for (int i=0; i<ITER*100000; i++) {
loop64<N/100000>(data);
}
long long int t1 = t();
for (int i=0; i<ITER*100000; i++) {
loop64<N/100000>(data+1);
}
long long int t2 = t();
for (int i=0; i<ITER; i++) {
loop64<N>(data);
}
long long int t3 = t();
for (int i=0; i<ITER; i++) {
loop64<N>(data+1);
}
long long int t4 = t();
printf(" 64-bit, cache: aligned: %8.4f GB/sec unaligned: %8.4f GB/sec, difference: %0.3f%%\n", (double)N*ITER/(t1-t0)/1000, (double)N*ITER/(t2-t1)/1000, 100.0*(t2-t1)/(t1-t0)-100.0f);
printf(" 64-bit, mem: aligned: %8.4f GB/sec unaligned: %8.4f GB/sec, difference: %0.3f%%\n", (double)N*ITER/(t3-t2)/1000, (double)N*ITER/(t4-t3)/1000, 100.0*(t4-t3)/(t3-t2)-100.0f);
}
{
long long int t0 = t();
for (int i=0; i<ITER*100000; i++) {
loop128a<N/100000>(data);
}
long long int t1 = t();
for (int i=0; i<ITER*100000; i++) {
loop128u<N/100000>(data+1);
}
long long int t2 = t();
for (int i=0; i<ITER; i++) {
loop128a<N>(data);
}
long long int t3 = t();
for (int i=0; i<ITER; i++) {
loop128u<N>(data+1);
}
long long int t4 = t();
printf("128-bit, cache: aligned: %8.4f GB/sec unaligned: %8.4f GB/sec, difference: %0.3f%%\n", (double)N*ITER/(t1-t0)/1000, (double)N*ITER/(t2-t1)/1000, 100.0*(t2-t1)/(t1-t0)-100.0f);
printf("128-bit, mem: aligned: %8.4f GB/sec unaligned: %8.4f GB/sec, difference: %0.3f%%\n", (double)N*ITER/(t3-t2)/1000, (double)N*ITER/(t4-t3)/1000, 100.0*(t4-t3)/(t3-t2)-100.0f);
}
}
最佳答案
计时方法。我可能会进行设置,以便由命令行参数选择测试,因此我可以使用perf stat ./unaligned-test
对其进行计时,并获得性能计数器的结果,而不仅仅是每次测试的挂钟时间。这样,由于我可以测量核心时钟周期,所以我不必在意涡轮增压/省电。 (除非禁用turbo和其他频率变化,否则它与gettimeofday
/rdtsc
引用周期不同。)
您只测试吞吐量,而不是等待时间,因为没有一个负载是相关的。
您的缓存号将比您的内存号更糟,但是您可能不会意识到这是因为您的缓存号可能是由于split-load registers数量的瓶颈所致,该cache-fetch width might be narrower than the line size处理跨越缓存行边界的加载/存储。对于顺序读取,高速缓存的外部级别仍然始终只会看到对整个高速缓存行的请求序列。只有执行单元从L1D获取数据才需要关心对齐。要测试非缓存情况下的未对齐情况,您可以分散负载,因此缓存行拆分将需要将两条缓存行放入L1中。
高速缓存行的宽度为64B1,因此您始终在测试高速缓存行拆分和高速缓存行内访问的混合情况。测试始终拆分的负载将使拆分负载的微体系结构资源面临更大的瓶颈。 (实际上,取决于您的CPU,@BeeOnRope says that AMD CPUs may care about 16B and 32B boundaries。近期的Intel CPU可以从缓存行内部获取所有未对齐的块,但这是因为它们具有特殊的硬件来加快存储速度。其他CPU可能仅在以自然方式获取时才是最快的。对齐的16B块或其他内容。Store-to-Load Forwarding and Memory Disambiguation in x86 Processors。)
您根本没有测试存储->负载转发。对于现有测试,以及一种以可视化的方式显示不同比对结果的好方法,请参阅此stuffedcow.net博客文章:Intel's optimization manual。
通过内存传递数据是一个重要的用例,未对齐+高速缓存行拆分可能会干扰某些CPU上的存储转发。要正确测试,请确保测试不同的错位,而不仅仅是1:15(向量)或1:3(整数)。 (您目前仅测试相对于16B对齐的+1偏移)。
我忘记了它是仅用于存储转发还是常规加载,但是当加载跨高速缓存行边界平均分配(8:8向量,也可能是4:4或2:2)时,惩罚可能会更少整数分割)。您应该对此进行测试。 (我可能正在考虑P4 lddqu
或Core 2 movqdu
)
Why is integer assignment on a naturally aligned variable atomic on x86?具有大的未对齐表与从宽商店到完全包含在其中的狭窄重载的商店转发。在某些CPU上,即使宽存储区是自然对齐的,这也适用于更多情况,即使它没有跨越任何高速缓存行边界也是如此。 (也许在SnB/IvB上,因为它们使用带有16B存储区的存储区L1高速缓存,并且在这些存储区之间拆分会影响商店转发。
我没有重新检查手册,但是如果您真的想通过实验进行测试,那是您应该寻找的东西。)
这使我想起,未对齐的负载更有可能在SnB/IvB上引发缓存库冲突(因为一个负载可以接触两个库)。但是您不会从单个流中看到此负载,因为在一个周期内两次访问同一行中的同一存储库是很好的。它只能以不同的方式访问同一银行,而不会在同一周期中发生。 (例如,两个内存访问的间隔为128B的倍数时。)
您无需尝试测试4k页面拆分。它们比常规的高速缓存行拆分要慢,因为它们还需要两次TLB检查。 (不过,Skylake将其从〜100个周期的惩罚提高到了超过正常负载使用延迟的〜5个周期的惩罚)
您无法在对齐的地址上测试movups
,因此即使内存在运行时对齐,您也不会检测到movups
比Core2上的movaps
慢,并且更早。 (我认为即使在Core2中,不对齐的mov
加载最多8个字节也是可以的,只要它们不跨越高速缓存行边界即可。IDK您必须查看多大的CPU才能发现非矢量问题在一个缓存行中加载它。它只能是32位CPU,但是您仍然可以使用MMX或SSE甚至x87来测试8B加载。P5Pentium和更高版本保证对齐的8B加载/存储是原子的,但是P6和更高版本只要没有越过缓存行边界,就可以确保缓存的8B加载/存储是原子的。与AMD相比,即使8B边界对于原子性也很重要,即使在可缓存的内存中也可以保证。
查看Agner Fog的内容,以了解更多有关如何降低未对齐负载的速度的信息,并准备测试以解决这些情况。实际上,Agner可能不是最好的资源,因为他的微体系结构指南主要侧重于通过管道获得微指令。只是简要介绍了缓存行拆分的成本,而没有深入讨论吞吐量与延迟的关系。
另请参阅:Dark Shikari的博客(x264首席开发人员)的Cacheline splits, take two,谈论Core2上未对齐的加载策略:检查对齐并为该块使用其他策略是值得的。
脚注:
如今,
mov rax, [rax+...]
和
movzx/sx
进行了整数测试(在这种情况下,使用加载的值作为索引,因为它太窄而不能用作指针)。
;;; Linux x86-64 NASM/YASM source. Assemble into a static binary
;; public domain, originally written by peter@cordes.ca.
;; Share and enjoy. If it breaks, you get to keep both pieces.
;;; This kind of grew while I was testing and thinking of things to test
;;; I left in some of the comments, but took out most of them and summarized the results outside this code block
;;; When I thought of something new to test, I'd edit, save, and up-arrow my assemble-and-run shell command
;;; Then edit the result into a comment in the source.
section .bss
ALIGN 2 * 1<<20 ; 2MB = 4096*512. Uses hugepages in .bss but not in .data. I checked in /proc/<pid>/smaps
buf: resb 16 * 1<<20
section .text
global _start
_start:
mov esi, 128
; mov edx, 64*123 + 8
; mov edx, 64*123 + 0
; mov edx, 64*64 + 0
xor edx,edx
;; RAX points into buf, 16B into the last 4k page of a 2M hugepage
mov eax, buf + (2<<20)*0 + 4096*511 + 64*0 + 16
mov ecx, 25000000
%define ADDR(x) x ; SKL: 4c
;%define ADDR(x) x + rdx ; SKL: 5c
;%define ADDR(x) 128+60 + x + rdx*2 ; SKL: 11c cache-line split
;%define ADDR(x) x-8 ; SKL: 5c
;%define ADDR(x) x-7 ; SKL: 12c for 4k-split (even if it's in the middle of a hugepage)
; ... many more things and a block of other result-recording comments taken out
%define dst rax
mov [ADDR(rax)], dst
align 32
.loop:
mov dst, [ADDR(rax)]
mov dst, [ADDR(rax)]
mov dst, [ADDR(rax)]
mov dst, [ADDR(rax)]
dec ecx
jnz .loop
xor edi,edi
mov eax,231
syscall
asm-link load-use-latency.asm && disas load-use-latency &&
perf stat -etask-clock,cycles,L1-dcache-loads,instructions,branches -r4 ./load-use-latency
+ yasm -felf64 -Worphan-labels -gdwarf2 load-use-latency.asm
+ ld -o load-use-latency load-use-latency.o
(disassembly output so my terminal history has the asm with the perf results)
Performance counter stats for './load-use-latency' (4 runs):
91.422838 task-clock:u (msec) # 0.990 CPUs utilized ( +- 0.09% )
400,105,802 cycles:u # 4.376 GHz ( +- 0.00% )
100,000,013 L1-dcache-loads:u # 1093.819 M/sec ( +- 0.00% )
150,000,039 instructions:u # 0.37 insn per cycle ( +- 0.00% )
25,000,031 branches:u # 273.455 M/sec ( +- 0.00% )
0.092365514 seconds time elapsed ( +- 0.52% )
mov rax, [rax]
,因此周期= 4 * L1-dcache-loads。 4c延迟。我没有禁用涡轮增压之类的功能。由于内核没有任何问题,因此内核时钟周期是最佳的测量方法。
[base + 0..2047]
:4c负载使用延迟,11c缓存行拆分,11c 4k页拆分(即使在同一大页面内)。有关更多详细信息,请参见Is there a penalty when base+offset is in a different page than the base?:如果base+disp
与base
不在同一个页面中,则必须重播load uop。 [rax - 16]
。并非如此,不是disp8 vs. disp32。 rax
之外的目标进行测量,因此负载是独立的:
movzx/movsx
的吞吐量/延迟(包括WORD拆分)相同,因为它们是在加载端口中处理的(不同于某些AMD CPU,其中也有ALU uop)。
uops_dispatched_port.port_2
+
port_3
= 2x
mov rdi, [rdi]
的计数器,在另一个使用基本相同循环的测试中。 (这是一个从属负载情况,不受吞吐量限制。)直到AGU之后,您才能检测到拆分负载。
关于performance - 如何在x86_64上准确基准未对齐的访问速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45128763/
我想创建一个 Python 基准测试列表。现在我只找到了 this 中的标准基准测试问题和一些来自 Computer Language Benchmarks Game . Python 还有其他基准测
我正在使用 apache 提供的基准文件 TestDFSIO 测试我的 hadoop 配置。我正在根据本教程(资源 1)运行它: http://www.michael-noll.com/blog/20
我刚刚安装了 Ruby 企业版,想对我的系统 Ruby 运行一些基准测试。是否有我应该实现的规范基准测试? 最佳答案 最有趣最深入Ruby benchmarks Antonio Cangiano 的系
我已经生成了基准,用于比较使用 ffmpeg 工具缩小视频文件 (mp4) 的两种方法。 基准以这种格式记录: x.mp4 Output_Resolution : 360p Method : A re
我正在使用 codeigniter 制作一个网站。 如果用户在他的评论中写入 {memory_usage} 2.75MB 将显示给他。它不会给 codeigniter 编写的代码带来安全漏洞吗?有什么
我正在尝试对 XSLT 的两个版本进行基准测试。目前我使用 Visual Studio 进行调试,因为从 .NET 组件调用的 xml 转换。 VS 2010 是我用于开发的 IDE。 我得到的唯一线
我想知道如何测量每个节点的内存带宽(流基准)。我的这个程序仅在一个节点上进行测量,进程和线程的数量如下: MPI_Comm_size(MPI_COMM_WORLD, &numranks); MPI_C
我正在关注 performance test Dapper 社区创建的。 目前,我在运行测试 10000 次后得到以下信息: EF 5 = 21595 毫秒 ADO.NET = 52183 毫秒 小巧
为了测量 CPU 的峰值 FLOPS 性能,我编写了一个小的 C++ 程序。但是测量结果给我的结果比我的 CPU 的理论峰值 FLOPS 大。怎么了? 这是我写的代码: #include #incl
有没有办法在 JUnit 测试套件中放置简单的开始/停止计时? 当我创建一个测试套件类时,它看起来像这样,我可以运行它。但是我怎么能在这里放一个简单的长开始时间变量来显示所有测试运行了多长时间? pu
我想测试MySQL数据库的InnoDB和MyRock引擎之间的高强度写入。为此,我使用 sysbench 进行基准测试。我的要求是: 多线程并发写入同一张表。 支持批量插入(每次插入事务都会插入大量记
我正在尝试构建一个 Nodejs Web 应用程序。当我添加更多代码时,最好有一种方法来测试此类更改对性能的影响,如果可能的话,以及我的应用程序在哪些方面花费最多时间。我目前正在使用 mocha 作为
我希望编写一个简单的每秒帧数动画基准 Javascript 实用程序。 FPS 在这里可能是一个模糊的术语,但理想情况下,它可以让我更准确地比较和衡量不同动画 (CSS3/canvas/webgl)
我是 Python 新手。这是我的第一种解释语言。到目前为止,我曾经学习过Java。因此,当 Java 程序第一次运行时,它的执行速度比下一次要慢。reasi 正在缓存。 import time de
我在 Ubuntu 虚拟机中使用 Apache 2.4.2。我用它来加载测试,向某些 HTTPS url 发送请求。失败请求数为零。但是我的请求都无法真正处理(已经在数据库中查找)。使用相同的 url
(我不确定这是否应该在 https://softwareengineering.stackexchange.com/ 上,如果您认为是,请评论) 我即将为我的学士论文创建 WebGL 实现的基准。我不
编辑: Clojure 基准测试已达到 the Benchmarks Game 。 我已经制作了这个问题社区 wiki 并邀请其他人保持更新。 有人知道 Clojure 的性能基准吗? 我自己做了一些
关注 this benchmark BSON 需要更多的磁盘空间和时间来创建、序列化、反序列化和遍历所有元素。 BSON 的一大优势是,它的遍历速度要快得多。那么这个基准有什么问题呢? 最佳答案 你的
我正在 NextFlow 上执行分散-聚集操作。 它看起来像下面这样: reads = PATH+"test_1.fq" outdir = "results" split_read_ch = chan
我无法让apache benchmark与我的网站配合使用。每当我发出此命令时 ab https://example.com/ 我会得到这个输出错误: This is ApacheBench, Ver
我是一名优秀的程序员,十分优秀!