我正在创建一个RandomAccessFile对象,以便通过多个线程写入文件(在SSD上).每个线程都尝试在文件中的特定位置写一个直接字节缓冲区,并确保线程写入的位置不会与另一个线程重叠:
file_.getChannel().write(buffer, position);
Run Code Online (Sandbox Code Playgroud)
where file_的实例是RandomAccessFile和buffer直接字节缓冲区.
对于RandomAccessFile对象,由于我没有使用fallocate来分配文件,并且文件的长度在变化,这是否会利用底层媒体的并发性?
如果不是,在创建文件时如果没有调用fallocate,使用上述函数是否有任何意义?
的_mm_shuffle_ps()固有允许一个交织浮子投入低2个浮纱和高2个漂浮的输出.
例如:
R = _mm_shuffle_ps(L1, H1, _MM_SHUFFLE(3,2,3,2))
Run Code Online (Sandbox Code Playgroud)
将导致:
R[0] = L1[2];
R[1] = L1[3];
R[2] = H1[2];
R[3] = H1[3]
Run Code Online (Sandbox Code Playgroud)
我想知道整数数据类型是否有类似的内在可用?有两个__m128i变量和掩码进行交错的东西?
的_mm_shuffle_epi32()内在的,只需一个128位向量,而不是两个.
作为那些从事程序优化和性能调优的人的一般性问题,如何判断代码是CPU绑定还是内存绑定?我一般都理解这些概念,但如果我说'y'加载和存储量以及'2y'计算,那么如何找到瓶颈是什么?
你也可以弄清楚你花在大部分时间上的确切位置并说,如果你将'x'数据量加载到缓存中(如果它的内存绑定),在每次循环迭代中,那么你的代码运行得更快?除了反复试验之外,有没有精确的方法来确定这个'x'?
您是否会使用任何工具,例如IA-32或IA-64架构?Doest VTune有帮助吗?
例如,我目前正在做以下事情:
我有26个8*8复数双矩阵,我必须对这26个矩阵中的每一个执行长度为8的(~4000)向量的MVM(矩阵向量乘法).我使用SSE来执行复数乘法.
/*Copy 26 matrices to temporary storage*/
for(int i=0;i<4000;i+=2){//Loop over the 4000 vectors
for(int k=0;k<26;k++){//Loop over the 26 matrices
/*
Perform MVM in blocks of '2' between kth matrix and
'i' and 'i+1' vector
*/
}
}
Run Code Online (Sandbox Code Playgroud)
26个矩阵需要26kb(L1缓存为32KB),我已经将向量放在内存中,这样我就可以进行大步访问.一旦我在27个矩阵的向量上执行MVM,我就不再访问它们了,所以我不认为缓存阻塞会有所帮助.我使用了矢量化,但我仍然坚持60%的峰值性能.
我尝试将64个向量复制到临时存储中,对于外循环的每次迭代都认为它们将在缓存和帮助中,但它只会降低性能.我尝试以下列方式使用_mm_prefetch():当我完成大约一半的矩阵时,我将下一个'i'和'i + 1'向量加载到内存中,但这也没有帮助.
我已经做了所有这些假设它的内存限制,但我想知道肯定.有办法吗?
我正在使用以下内容在SSE和AVX中编写矩阵向量乘法:
for(size_t i=0;i<M;i++) {
size_t index = i*N;
__m128 a, x, r1;
__m128 sum = _mm_setzero_ps();
for(size_t j=0;j<N;j+=4,index+=4) {
a = _mm_load_ps(&A[index]);
x = _mm_load_ps(&X[j]);
r1 = _mm_mul_ps(a,x);
sum = _mm_add_ps(r1,sum);
}
sum = _mm_hadd_ps(sum,sum);
sum = _mm_hadd_ps(sum,sum);
_mm_store_ss(&C[i],sum);
}
Run Code Online (Sandbox Code Playgroud)
我对AVX使用了类似的方法,但最后,由于AVX没有等效的指令_mm_store_ss(),我用过:
_mm_store_ss(&C[i],_mm256_castps256_ps128(sum));
Run Code Online (Sandbox Code Playgroud)
SSE代码比串行代码的速度提高了3.7.但是,AVX代码比串行代码的速度提高了4.3.
我知道将SSE与AVX一起使用可能会导致问题,但我使用g ++编译了-mavx'标志,这应该删除SSE操作码.
我也可以使用:_mm256_storeu_ps(&C[i],sum)做同样的事情,但加速是一样的.
关于我还能做些什么来提高性能的任何见解?它可以与:performance_memory_bound相关,虽然我不明白该线程的答案.
此外,即使包含"immintrin.h"头文件,我也无法使用_mm_fmadd_ps()指令.我启用了FMA和AVX.
在SSE中,如果我有一个包含4个浮点数的128位寄存器,即
A = a b c d ('a','b','c','d' are floats and 'A' is a 128-bit SSE register)
Run Code Online (Sandbox Code Playgroud)
和
B = e f g h
Run Code Online (Sandbox Code Playgroud)
然后,如果我想
C = a e b f
Run Code Online (Sandbox Code Playgroud)
我可以简单地做:
C = _mm_unpacklo_ps(A,B);
Run Code Online (Sandbox Code Playgroud)
同样如果我想要
D = c g d h
Run Code Online (Sandbox Code Playgroud)
我可以:
D = _mm_unpackhi_ps(A,B);
Run Code Online (Sandbox Code Playgroud)
如果我有一个包含双精度的AVX寄存器,是否可以用一条指令执行相同操作?
基于这些内部函数是如何工作的,我知道,我不能使用_mm256_unpacklo_pd(),_mm256_shuffle_pd(),_mm256_permute2f128_pd()或_mm256_blend_pd().除了这些我还可以使用或者我必须使用上述说明的组合吗?
假设我有以下课程:
class A
{
public:
...
...
void incrementN() {++n_;}
uint64_t getN() {return n_;}
private:
std::atomic<uint64_t> n_;
...
...
};
Run Code Online (Sandbox Code Playgroud)
假设我初始化了类中的所有其他变量,除了n_并且这不是线程本地存储,因此没有零初始化.
我创建了A类的对象,并继续调用incrementN().
如果在某些时候我想要的值n_,并且我调用getN(),这会导致load()原子的例程n_崩溃吗?
如果我有一个AVX寄存器,其中有4个双打,并且我想将其反向存储在另一个寄存器中,是否可以使用单个内部命令执行此操作?
例如:如果我在SSE寄存器中有4个浮点数,我可以使用:
_mm_shuffle_ps(A,A,_MM_SHUFFLE(0,1,2,3));
Run Code Online (Sandbox Code Playgroud)
我可以使用_mm256_permute2f128_pd()吗?我不认为你可以用上面的内在来解决每个人的双重问题.
sse ×5
c ×4
avx ×3
c++ ×2
filechannel ×1
java ×1
optimization ×1
performance ×1
simd ×1
stdatomic ×1