我通常把我的平等条件写成:
if(0==x)
Run Code Online (Sandbox Code Playgroud)
和许多人一样
if(x==0)
Run Code Online (Sandbox Code Playgroud)
这样编译器会告诉我什么时候不小心输入=而不是==.
有人告诉我,有些编译器将其实现为两个寄存器加载,而不是使用不等于零的操作,因此效率较低.
有人知道这是否是一个合理的评论?
我最近决定尝试一下 Java 的新孵化矢量 API,看看它能达到多快。我实现了两种相当简单的方法,一种用于解析 int,另一种用于查找字符串中字符的索引。在这两种情况下,与标量方法相比,我的矢量化方法都慢得令人难以置信。
这是我的代码:
public class SIMDParse {
private static IntVector mul = IntVector.fromArray(
IntVector.SPECIES_512,
new int[] {0, 0, 0, 0, 0, 0, 1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1},
0
);
private static byte zeroChar = (byte) '0';
private static int width = IntVector.SPECIES_512.length();
private static byte[] filler;
static {
filler = new byte[16];
for (int i = 0; i < 16; i++) {
filler[i] = zeroChar;
}
}
public static int parseInt(String str) …Run Code Online (Sandbox Code Playgroud) 当 8 位指令和 64 位 x64/Amd64 处理器上的 64 位指令除了位宽之外相似/相同时,这些指令之间是否存在执行时序差异?有没有办法找到执行这两个微小汇编函数的真实处理器时序?
-谢谢。
; 64 bit instructions
add64:
mov $0x1, %rax
add $0x2, %rax
ret
; 8 bit instructions
add8:
mov $0x1, %al
add $0x2, %al
ret
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写 BSF 的矢量化实现作为练习,但我陷入困境,它不起作用。
算法:
short bitScanForward(int16_t bb)
{
constexpr uint16_t two = static_cast<uint16_t>(2);
constexpr uint16_t zero = static_cast<uint16_t>(0);
uint16_t lsb;
bb &= -bb;
lsb = (unsigned short)bb
| (unsigned short)(bb >> short(8));
return static_cast<short>(((((((unsigned short)(bb >>
short(8)) != zero) * two)
+ ((lsb & unsigned short(0xf0f0)) != zero)) * two)
+ ((lsb & unsigned short(0xcccc)) != zero)) * two)
+ ((lsb & unsigned short(0xaaaa)) != zero);
}
Run Code Online (Sandbox Code Playgroud)
我的矢量代码:
[[nodiscard]] inline __m128i _mm_cmpneq_epi16(const __m128i& a, const __m128i& …Run Code Online (Sandbox Code Playgroud) 我正在尝试弄清楚如何在 C++ 中读取此汇编代码。
这是代码:
unsigned __int64 high_perf_time;
unsigned __int64 *dest = &high_perf_time;
__asm
{
_emit 0xf // these two bytes form the 'rdtsc' asm instruction,
_emit 0x31 // available on Pentium I and later.
mov esi, dest
mov [esi ], eax // lower 32 bits of tsc
mov [esi+4], edx // upper 32 bits of tsc
}
__int64 time_s = (__int64)(high_perf_time / frequency); // unsigned->sign conversion should be safe here
__int64 time_fract = (__int64)(high_perf_time % frequency); // unsigned->sign conversion should …Run Code Online (Sandbox Code Playgroud) 我需要遍历大量(2D)数据,并且仅有时处理特殊情况。对于我的应用程序来说,速度是最关键的因素。
(我)很快想到的选择是:
选项A:
void ifInLoop(bool specialCase, MyClass &acc) {
for (auto i = 0; i < n; ++i) {
for (auto j = 0; j < n; ++j) {
if (specialCase) {
acc.foo();
} else {
acc.bar();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
选项B:
void loopsInIf(bool specialCase, MyClass &acc) {
if (specialCase) {
for (auto i = 0; i < n; ++i) {
for (auto j = 0; j < n; ++j) {
acc.foo();
}
}
} else { …Run Code Online (Sandbox Code Playgroud) 我最近问了一个问题: 为什么迭代std :: array比迭代std :: vector快得多?
正如人们很快指出的那样,我的基准测试存在许多缺陷。因此,当我尝试确定基准时,我注意到这std::vector并不慢std::array,实际上,情况恰恰相反。
#include <vector>
#include <array>
#include <stdio.h>
#include <chrono>
using namespace std;
constexpr int n = 100'000'000;
vector<int> v(n);
//array<int, n> v;
int main()
{
int res = 0;
auto start = chrono::steady_clock::now();
for(int x : v)
res += x;
auto end = chrono::steady_clock::now();
auto diff = end - start;
double elapsed =
std::chrono::duration_cast<
std::chrono::duration<double, std::milli>
>(end - start).count();
printf("result: %d\ntime: %f\n", res, elapsed);
}
Run Code Online (Sandbox Code Playgroud)
我尝试从以前的基准进行改进的事情:
-O3标志速度 …对于那些已经测量过或对此类注意事项有深入了解的人,假设您必须执行以下操作(仅选择任何示例)浮点运算符:
float calc(float y, float z)
{ return sqrt(y * y + z * z) / 100; }
Run Code Online (Sandbox Code Playgroud)
哪里y和z可能是非正规数,让我们假设两种可能的情况,其中只有 y,只有 z,或者两者,以完全随机的方式,可以是非正规数
现在假设我想避免处理非正规数的性能损失,我只想将它们视为 0,然后通过以下方式更改该段代码:
float calc(float y, float z)
{
bool yzero = y < 1e-37;
bool zzero = z < 1e-37;
bool all_zero = yzero and zzero;
bool some_zero = yzero != zzero;
if (all_zero)
return 0f;
float ret;
if (!some_zero) ret = sqrt(y * y + z * z);
else if (yzero) …Run Code Online (Sandbox Code Playgroud) 我有一个可重现的样本,如下所示 -
#include <iostream>
#include <chrono>
#include <immintrin.h>
#include <vector>
#include <numeric>
template<typename type>
void AddMatrixOpenMP(type* matA, type* matB, type* result, size_t size){
for(size_t i=0; i < size * size; i++){
result[i] = matA[i] + matB[i];
}
}
int main(){
size_t size = 8192;
//std::cout<<sizeof(double) * 8<<std::endl;
auto matA = (float*) aligned_alloc(sizeof(float), size * size * sizeof(float));
auto matB = (float*) aligned_alloc(sizeof(float), size * size * sizeof(float));
auto result = (float*) aligned_alloc(sizeof(float), size * size * sizeof(float));
for(int i = …Run Code Online (Sandbox Code Playgroud) 抱歉,我一直不明白这里的规则。我已经删除了所有重复的帖子。这是第一个相关问题。\n请不要将此帖子标记为我另一篇帖子的重复(执行次数减少 3 倍,但执行效率几乎不变。在 C 中),即使代码有些相似,他们提出了截然不同的问题。这也是我同一天发现的两个问题。类似的帖子因“误判”而被重复,然后被关闭。可能是我没有把这个问题说清楚。我真的很希望得到答案,所以我重新发布了它。希望大家能够看清问题,非常感谢!
\n在下面的C代码中,我在第一次测试时间的循环中添加了一个“if”语句,执行时间完全相同。从理论上讲,它应该更慢。尽管分支预测可以使它们的性能几乎相同,但它实际上变得更快。这是什么原理呢?我尝试使用clang和gcc编译器分别在Mac和Linux环境中运行,并尝试了各种优化级别。为了防止缓存受到影响,我让速度较快的先执行,但有冗余代码的循环执行得更快。
\n如果您认为我的描述不可信,请将以下代码编译到您的计算机中并运行。希望有人能为我回答这个问题\xef\xbc\x8c谢谢。
\nC代码:
\n#include <stdio.h>\n#include <time.h>\n#include <stdlib.h>\n#include <string.h>\n\n#define TLen 300000000\n#define SLen 10\n\nint main(int argc, const char * argv[]) {\n srandom((unsigned)time(NULL));\n \n // An array to increase the index,\n // the range of its elements is 1-256\n int rand_arr[128];\n for (int i = 0; i < 128; ++i)\n rand_arr[i] = random()%256+1;\n \n // A random text(very long), the range of its elements is 0-127\n char *tex = malloc((sizeof *tex) * …Run Code Online (Sandbox Code Playgroud)