我正在深入研究指针,因为我不认为我对指针有很好的了解,并在维基百科上看到以下几行:
处理数组时,关键查找操作通常涉及一个称为地址计算的阶段,该阶段涉及构造指向数组中所需数据元素的指针.如果数组中的数据元素具有可被2的幂整除的长度,则此算法通常更有效.
为什么会这样?
#include <stdio.h>
#include <time.h>
#define N 32768
char a[N][N];
char b[N][N];
int main() {
int i, j;
printf("address of a[%d][%d] = %p\n", N, N, &a[N][N]);
printf("address of b[%5d][%5d] = %p\n", 0, 0, &b[0][0]);
clock_t start = clock();
for (j = 0; j < N; j++)
for (i = 0; i < N; i++)
a[i][j] = b[i][j];
clock_t end = clock();
float seconds = (float)(end - start) / CLOCKS_PER_SEC;
printf("time taken: %f secs\n", seconds);
start = clock();
for (i = 0; …Run Code Online (Sandbox Code Playgroud) 我正在研究摄像机拍摄的1000万像素图像.
目的是在矩阵(二维阵列)中记录每个像素的灰度值.
我第一次使用GetPixel,但它需要25秒才能完成.现在我使用Lockbits但是它需要10秒,如果我不将结果保存在文本文件中则需要3秒.
我的导师说他们不需要注册结果,但3秒仍然太慢.我在我的程序中做错了什么,或者我的应用程序有比Lockbits更快的东西吗?
这是我的代码:
public void ExtractMatrix()
{
Bitmap bmpPicture = new Bitmap(nameNumber + ".bmp");
int[,] GRAY = new int[3840, 2748]; //Matrix with "grayscales" in INTeger values
unsafe
{
//create an empty bitmap the same size as original
Bitmap bmp = new Bitmap(bmpPicture.Width, bmpPicture.Height);
//lock the original bitmap in memory
BitmapData originalData = bmpPicture.LockBits(
new Rectangle(0, 0, bmpPicture.Width, bmpPicture.Height),
ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
//lock the new bitmap in memory
BitmapData newData = bmp.LockBits(
new Rectangle(0, 0, bmpPicture.Width, bmpPicture.Height),
ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
//set …Run Code Online (Sandbox Code Playgroud) 我正在研究多核机器上的并行算法的性能.我使用循环重新排序(ikj)技术进行了矩阵乘法的实验.
串行执行结果如下图所示.L1数据高速缓存命中循环次序ikj和kij所有大小的nXn矩阵接近100%(图1盒号1和2),你可以看到循环次序ikj的大小为2048和4096突然L2数据缓存命中减少%50(图2盒号1和2)也在L2指令缓存中命中同样如此.对于这2个大小的L1数据高速缓存命中的情况与其他大小(256,512,1024)大约是%100.在指令和数据缓存命中中,我找不到任何合理的斜率原因.任何人都可以告诉我如何找到原因?
你认为L2统一缓存对加剧问题有什么影响吗?但是仍然是什么导致这种减少算法和性能的特征应该我找到原因.
实验机是Intel e4500,带2Mb L2缓存,缓存行64,os是fedora 17 x64,带gcc 4.7 -o无编译器优化
简明扼要的完整问题?
my problem is that why sudden decrease of about 50% in both L2 data and instruction cache happens in only ikj & kij algorithm as it's boxed and numbered 1 & 2 in images, but not in other loop variation?
*Image 1*
Run Code Online (Sandbox Code Playgroud)

*Image 2*
Run Code Online (Sandbox Code Playgroud)

*Image 3*
Run Code Online (Sandbox Code Playgroud)

*Image 4*
Run Code Online (Sandbox Code Playgroud)

*Image 5*
Run Code Online (Sandbox Code Playgroud)
尽管存在上述问题,但ikj&kij算法的时序没有增加.但也比其他人快.

ikj和kij算法是循环重排序技术的两种变体/
kij算法
For (k=0;k<n;k++)
For(i=0;i<n;i++){
r=A[i][k];
For (j=0;j<n;j++)
C[i][j]+=r*B[k][j]
}
Run Code Online (Sandbox Code Playgroud)
ikj算法
For (i=0;i<n;i++)
For(k=0;k<n;k++){
r=A[i][k];
For (j=0;j<n;j++) …Run Code Online (Sandbox Code Playgroud) 我想学习使用英特尔Haswell CPU微体系结构的并行编程.关于在asm/C/C++ /(任何其他语言)中使用SIMD:SSE4.2,AVX2?你能推荐书籍,教程,网络资源,课程吗?
谢谢!
警告:实际上它不是由于2的幂而是奇偶校验.请参阅编辑部分.
我找到了一个显示相当奇怪行为的代码.
代码使用2D数组(大小x大小).当size为2的幂时,代码的速度在10%到40%之间,最慢的是size = 32.
我用英特尔编译器获得了这些结果.如果我使用gcc 5.4编译,2问题的能力消失但代码慢3倍.在不同的CPU上测试它,我认为它应该足够可重复.
码:
#define N 10000000
unsigned int tab1[TS][TS];
void simul1() {
for(int i=0; i<TS; i++)
for(int j=0; j<TS; j++) {
if(i > 0)
tab1[i][j] += tab1[i-1][j];
if(j > 0)
tab1[i][j] += tab1[i][j-1];
}
}
int main() {
for(int i=0; i<TS; i++)
for(int j=0; j<TS; j++)
tab1[j][i] = 0;
for(int i=0; i<N; i++) {
tab1[0][0] = 1;
simul1();
}
return tab1[10][10];
}
Run Code Online (Sandbox Code Playgroud)
汇编:
icc:
icc main.c -O3 -std=c99 -Wall -DTS=31 -o …Run Code Online (Sandbox Code Playgroud) 我在C中构造函数的偏导数.该过程主要由大量小循环组成.每个循环负责填充矩阵的列.因为矩阵的大小很大,所以应该有效地编写代码.我对实施有很多计划,我不想深入了解细节.
我知道智能编译器会尝试自动利用缓存.但我想了解更多使用缓存和编写高效代码和高效循环的细节.如果提供一些资源或网站,我将不胜感激,因此我可以更多地了解如何在减少内存访问时间和利用优势方面编写有效代码.
我知道我的请求看起来很草率,但我不是电脑人.我做了一些研究但没有成功.所以,任何帮助表示赞赏.
谢谢
为什么矩阵加法比矩阵向量乘法需要更长的时间?
矩阵仅添加成本n ^ 2 add,而Matrix-Vector Multiplication需要n*(n-1)add和n ^ 2乘法.
但是,在Eigen中,Matrix Add需要的时间是Matrix-Vector Multiplication的两倍.是否存在加速Eigen中Matrix Add操作的选项?
#include <eigen3/Eigen/Eigen>
#include <iostream>
#include <ctime>
#include <string>
#include <chrono>
#include <fstream>
#include <random>
#include <iomanip>
using namespace Eigen;
using namespace std;
int main()
{
const int l=100;
MatrixXf m=MatrixXf::Random(l,l);
MatrixXf n=MatrixXf::Random(l,l);
VectorXf v=VectorXf::Random(l,1);
MatrixXf qq=MatrixXf::Random(l,1);
MatrixXf pp=MatrixXf::Random(l,l);
auto start = chrono::steady_clock::now();
for(int j=0;j<10000;j++)
qq=m*v;
auto end = chrono::steady_clock::now();
double time_duration=chrono::duration_cast<chrono::milliseconds>(end - start).count();
std::cout << setprecision(6) << "Elapsed time in seconds : "<< time_duration/1000<< "s" << std::endl;
auto …Run Code Online (Sandbox Code Playgroud)