我们正在对现有Java程序进行基准测试 它们是旨在从多核CPU中受益的线程应用程序.我们想测量内核数量对运行速度的影响,但我们不愿意(也无法)更改这些应用程序的代码.
当然,我们可以在不同的机器上测试软件,但这样既昂贵又复杂.我们宁愿拥有一个软件解决方案.
注意:您可以假设测试平台是Windows,Linux或Mac.理想情况下,我们希望能够在这两个平台上运行测试.
我最近发现 AVX2 没有 __m256i 的 popcount,我发现做类似事情的唯一方法是遵循 Wojciech Mula 算法:
__m256i count(__m256i v) {
__m256i lookup = _mm256_setr_epi8(0, 1, 1, 2, 1, 2, 2, 3, 1, 2,
2, 3, 2, 3, 3, 4, 0, 1, 1, 2, 1, 2, 2, 3,
1, 2, 2, 3, 2, 3, 3, 4);
__m256i low_mask = _mm256_set1_epi8(0x0f);
__m256i lo =_mm256_and_si256(v,low_mask);
__m256i hi = _mm256_and_si256( _mm256_srli_epi32(v, 4), low_mask);
__m256i popcnt1 = _mm256_shuffle_epi8(lookup,lo);
__m256i popcnt2 = _mm256_shuffle_epi8(lookup,hi);
__m256i total = _mm256_add_epi8(popcnt1,popcnt2);
return _mm256_sad_epu8(total,_mm256_setzero_si256());
}
Run Code Online (Sandbox Code Playgroud)
LLVM 的 clang/clang++ 允许您为整个代码区域指定属性。语法如下:
// the following works fine under clang:
#pragma clang attribute push(__attribute__((target("sse4.2"))), apply_to=function)
void f(){}
#pragma clang attribute pop
Run Code Online (Sandbox Code Playgroud)
在此示例中,该函数f将在支持 SSE4.2 指令集的情况下进行编译。这将适用于attribute push和之间的所有函数attribute pop。
如果我们添加一个命名空间呢?
namespace joe {
#pragma clang attribute push(__attribute__((target("sse4.2"))), apply_to=function)
void g() {}
#pragma clang attribute pop
}
Run Code Online (Sandbox Code Playgroud)
它失败了'error: expected unqualified-id'。显然attribute,编译器不需要关键字。
鉴于命名空间的常见程度,这个问题有点出乎意料。当然,可以避免命名空间来解决这个问题,但这有点不雅。
有更好的解决方法吗?
我已经用所有最近的 LLVM clang++ 编译器(最高 8.0)验证了这个问题。
avx ×1
avx2 ×1
benchmarking ×1
c++ ×1
clang ×1
clang++ ×1
intel ×1
java ×1
performance ×1
sse ×1